手机版

PHP实现微信小程序用户授权的工具类示例

时间:2021-08-27 来源:互联网 编辑:宝哥软件园 浏览:

提前准备工作

1.申请小程序,申请地址:门户2。仔细阅读小程序用户授权登录的官方文档:《用户授权登陆的流程》 3。仔细阅读微信用户数据解密相关文档:《用户数据解密说明文档》 4。在小程序后台配置对应的后端请求地址,路径为:开发-开发设置,如图

5.如果一个小程序需要多个小程序打开,需要绑定到微信开放平台上的开发者账号。如果不需要union_id,请忽略

6.服务器准备一个用户授权的接口,假设接口链接是http://test.dev.com/user/authorization,并且该接口接受以下参数

代码:微信登录界面返回的登录凭证,用户获取session_key iv:微信小程序登录界面返回的向量,用于数据解密encrypted_data :微信获取用户信息界面返回的用户加密数据,用于后端分析签名加密数据界面返回如下数据

{'errcode' : 200,' msg' :' success ',' data' : {'uid' : 34098,' union id' :' XXX ',}} 6。创建表格

1)用户表,其中比较重要的字段是union_id,因为我们有多个小程序和微信官方账号,我们用这个来区分唯一的用户号。

如果存在“jz_wxa_user ”,则删除表;CREATE TABLE ` JZ _ wxa _ user `(` id ' int(10)无符号NOT NULL AUTO_INCREMENT,` uid ' big int(18)DEFAULT NULL,` OpenID ' varchar(255)CHARACTER SET utf8 DEFAULT NULL COMMENT ' OpenID ',` user _ name ' varchar(100)CHARACTER SET utf8 MB 4 DEFAULT ' ',` nick _ name ` varchar(100)collate utf8 MB 4 _ unicode _ cide fault ' ' COMMENT '用户昵称,` sex ' enum(' 0 ',' 1)字符集utf8 ` city `varchar (100)字符集utf8默认空注释' city ',` country `varchar (100)字符集utf8默认空注释' country ',` wx _ union _ id `varchar (255)字符集utf8默认空注释'公共平台的唯一id ',` from _ URL`varchar (255)字符集utf8默认空注释'源URL ',` created _ at ` timestamp null default null,` updated _ at ` timestamp null default null,` from _ appid`varchar (30) ` wx _ header ` varchar(150)collecteut F8 MB 4 _ unicode _ cide fault ''注释'微信头像',` GH _ openid ` varchar(60)collecteut F8 MB 4 _ unicode _ cide fault ' '注释'微信微信官方账号OpenID ',` phone`varchar (30)字符集utf8默认' '注释'手机号码'、主键(` id ')、键` idx _ uid _ union _ id' (`uid '、` wx _ union _ id `) ENGINE=InnoDB 实施步骤

用户授权时序图

键盘编码器

小程序结束

在小程序端获取用户信息的过程

1)调用登录方法获取代码2)调用getUserInfo方法获取用户的加密数据3)调用后端用户授权接口将用户信息保存到服务器4)将后端接口返回的uid和unionid作为全局参数保存到localstorage

获取用户的授权信息

getUid:function(cf){ var那=这个wx。登录({ success : function(RESS){ var code=RESS。代码wx。getuser info({用凭据:真,成功:函数(RES){那。globaldata。userinfo=RES . userinfo那个。已授权(代码、res.signature、res.iv、res.rawData、res.encryptedData,cf)})}),authorize:函数(代码,签名,iv,rawData,encryptedData,cf){ var那=这个var data obj={代码:代码,签名:签名,iv: iv,rawData,encryptedData }控制台。日志('代码3:)加密(参数)var URL=那个。数据。API _ DOMAIN ' 2/用户/授权?param=' param wx。请求({ URL : URL,method: 'GET ',标头: { '内容类型' : ' application/JSON ' }),成功:函数(RES){ if(RES . data。错误代码==200){ wx。HideToast()wx。Setstorage({ key : ' uid ',data : RES . data。uid,success :函数(){ 0服务端

入口方法

/** * api接口开发* 获取详情的接口* @param $uid用户编号* @param $iv向量* @param $encryptedData微信加密的数据* @param $rawData判断是否为今天* @ param $签名签名* @ return array */public static function authorization($ appid,$appsecret,$code,$iv,$encryptedData,$rawData,$ signature){ $ result=self : dedecadex data($ appid,$appsecret,$code,$iv,$ encryptedData);if($result['errcode']!=200){返回$ result} //处理微信授权的逻辑$ wxUserData=$ result[' data '];错误日志('授权数据===============');error _ log(JSON _ encode($ wxUserData));$ uid=wxauser服务: regwxa user($ wxUserData);$ data[' uid ']=$ uid[' uid '];$ data[' union id ']=$ uid[' union id '];$ result[' data ']=$ data;返回$ result} /** *解密微信的数据* @ param $代码wx.login接口返回的代码* @param $iv wx.getUserInfo接口或者wx.getWeRunData返回的iv * @ param $ encryptedData wx。户信息接口或者wx.getWeRunData返回的加密数据* @返回数组*/公共静态函数decodeWxData($appid,$appsecret,$code,$iv,$ encryptedData){ $会话密钥URL=sprintf(' % s?appid=% s secret=% sjs _ code=% s grant _ type=authorization _ code ',config(' param。wxa _ user _ info _ session _ key _ URL’),$appid,$appsecret,$ code);$ RTNjson=curlRequest($ SessionKeYurl);$data=json_decode($rtnJson,true);错误日志('授权wx返回数据=========');error _ log($ RTNjson);if(isset($ data[' errcode ']){ return $ data;} $ session key=$ data[' session _ key '];$ wxHelper=new WxBizDataHelper($ appid,$sessionKey,$encryptedData,$ iv);$ data[' errcode ']=200;$ data[' data ']=[];if(!$ wxData=$ wxHelper-getData()){ $ data[' errcode ']=-1;}else{ error_log('当前women's extra large size 女式特大号返回数据为==========')。JSON _ encode($ WxDATa));$ data[' data ']=$ wxData;}返回$ data}保存用户信息的方法

/** * 保存用户信息的方法* @ param $ Wxauserdata * @ param $ reg froh表示是否从公众号进行注册*/public函数regWxaUser($wxaUserData,$ regFromGh=false){ $ value=$ wxaUserData[' union id '];$ key=getCacheKey(' redis _ key。cache _ key。zset _ list。锁定').$ value $ new expire=redis help :3360 getlock($ key);$ data=$ this-storeWxaUser($ wxaUserData,$ regFromGh);redishelper :释放锁($ key,$ new expire);返回$数据;} /** * 保存信息* @ param $ wxaUserData * @返回混合*/公共函数storeWxaUser($wxaUserData,$ regFromGh=false){ $ wxuserdata=$ wxaUserData[' union id '];if(!$ user=$ this-getbyxunionid($ wxUnionId)){ $ getAccountDataStartTime=time();//这里是因为需要统一账户获取uid,所以这个是用户中心的接口,如果没有这个流程,则直接使用数据if($ account data=account center help : regwxauser($ wxaUserData)){ $ getaccountdateendtime=time();$ account regtime=$ getaccount data end time-$ getaccount data start time;错误日志(' reg用户花费的时间为=========================')。$ account reg time);$ user=[' uid '=$ account data[' uid '],' user _ name '=$ account data[' user _ name '],' nick_name'=$wxaUserData['昵称],' sex'=$accountData['sex'],' wx _ union _ id '=$ account data[' wx _ union _ id '],' avatar '=isset($ account data[' avatar '])?$accountData['avatar']: ' ',from _ appid '=$ account data[' from _ appid '],'省份=$ wxuserdata['省份'],'城市=$ wxuserdata['城市'],'国家=$ wxuserdata['国家],' openId '=$ wxuserdata[' openId '],' wx _ header '=isset($ wxuserdata['头像URL '])?$wxaUserData['avatarUrl']: ' ',' gh_openid'=$regFromGh?$wxaUserData['openId']: ' ',];错误日志('插入数据==============')。JSON _ encode($ user));$ user=$ this-store($ user);$ regapi user end time=time();错误日志(' reg api用户花费时间====================')。($ regapi user end time-$ getaccountdatendtime));错误日志('在插入数据之后===============')。JSON _ encode($ user));} }else{ if(!$ user[' wx _ header ']){ $ updateData=[' id '=$ user[' id '],' uid'=$user['uid'],' wx _ header '=$ wxuserdata[' avatar URL '],];$ this-update($ updateData);} //同步用户的open id if($ wxaUserData[' OpenID ']!=$ user[' openId ']){ $ updateData=[' id '=$ user[' id '],' uid'=$user['uid'],' openid'=$wxaUserData['openId'],];$ this-update($ updateData);} } $ data[' uid ']=$ user[' uid '];$ data[' union id ']=$ wxUnionId;返回$数据;}根据珠蚌获取用户信息

/** * 根据珠蚌获取用户信息*/public函数getbyxunionid($ union id){ $ cacheKey=getCacheKey(' redis _ key。cache _ key。wxa _ user。信息').$ unionId$ value=$ this-记住($cacheKey,function()use($ union id){ $ UserInfo=wxa user :其中(' wx _ union _ id ',$ union id)-first();$ UserInfo=$ this-CompactUserInfo($ UserInfo);返回$ UserInfo });返回$ value}WxBizDataHelper工具类

?php/** *由PhpStorm创建*用户: Auser *时间: 11:17 */命名空间App \ Http \ Base \ Wx类WxBizDataHelper { private $ appid private $ seesionkey private $ encryptedData私人$ ivpublic function _ _ construct($ appid,$sessionKey,$encryptedData,$ iv){ $ this-appid=$ appid;$ this-seesionKey=$ session key;$ this-加密数据=$加密数据;$ this-iv=$ iv;}公共函数getData(){ $ PC=new WXBizDataCrypt($ this-appid,$ this-seesionKey);$ JSON=$ errCode=$ PC-decryptData($ this-encryptedData,$this-iv,$ JSON);$ data=[];if($ errCode==0){ $ data=JSON _ decode($ JSON,true);}返回$ data}}WXBizDataCrypt工具类

?php/** *由PhpStorm创建*用户: Auser *时间: 10:38 */命名空间App \ Http \ Base \ Wx使用App \ Http \ Base \ Wx \ Prpcrypt使用App \ Http \ Base \ Wx \ ErrorCode使用App \ Http \ Base \ Wx \ PKCS7Encoder类WXBizDataCrypt { private $ appid private $ session key/* * *构造函数* @param $sessionKey字符串用户在小程序登录后获取的会话密钥* @param $appid字符串小程序的appid */public function _ _ construct($ appid,$ session key){ $ this-session key=$ session key;$ this-appid=$ appid;} /** * 检验数据的真实性,并且获取解密后的明文* @param $encryptedData字符串加密的用户数据* @param $iv字符串与用户数据一同返回的初始向量* @ param $数据字符串解密后的原文* * @return int成功0,失败返回对应的错误码*/public函数decryptData($encryptedData,$iv,$ data){ if(strlen($ this-session key)!=24){返回错误代码: $ IllegalAesKey} $ AES密钥=base64 _ decode($ this-session key);if (strlen($iv)!=24){返回错误代码: $ IllegalIv} $ aesIV=base64 _ decode($ iv);$ AES密码=base64 _ decode($ encryptedData);$pc=新pr crypt($ AeKey);$result=$pc-decrypt($aesCipher,$ AES iv);if ($result[0]!=0) {返回$ result[0];} $ DataObj=JSON _ decode($ result[1]);if($ dataObj==NULL){返回错误代码: $ IllegalBuffer} if($dataObj-watermark-appid!=$ this-appid){返回错误代码: $ IllegalBuffer} $ data=$ result[1];返回错误代码错误代码:美元正常} }密码工具类

?php/** *由PhpStorm创建*用户: Auser *时间: 10:55 */命名空间App \ Http \ Base \ Wx类PRP crypt { public $ key public function _ _ construct($ key){ $ this-key=$ key;} /** * 对密文进行解密* @param字符串$aesCipher需要解密的密文* @param字符串$aesIV解密的初始向量* @返回字符串解密得到的明文*/public function decrypt($ AES cipher,$ aesIV){ try { $ module=MCRYPT _ module _ open(MCRYPT _ RIJNDAEL _ 128 ' ',MCRYPT _ MODE _ CBC ' ');mcrypt_generic_init($module,$this-key,$ aesIV);//解密$ decrypted=mdecrypt _ generic($ module,$ AES cipher);MC rypt _ generic _ definit($ module);MC rypt _ module _ close($ module);}捕获(异常$ e){ 0返回数组(错误代码: $ IllegalBuffer,null);}尝试{ $ result=pkcs7 encoder 2: decode($已声明);} catch(Exception $ e){//print $ e;返回数组(错误代码: $ IllegalBuffer,null);}返回数组(0,$ result);} }错误代码状态代码类

?php/** *由PhpStorm创建*用户: Auser *时间: 10:33 */命名空间App \ Http \ Base \ Wx类错误代码{公共静态$ OK=0;public static $ IllegalAesKey=-41001;public static $ IllegalIv=-41002;public static $ IllegalBuffer=-41003;public static $ decodabase 64错误=-41004;}以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

版权声明:PHP实现微信小程序用户授权的工具类示例是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。