事先准备工作
1.申请一个小程序,申请地址:传送门
2.仔细阅读小程序的用户授权登陆官方文档: 《用户授权登陆的流程》
3.仔细阅读微信用户数据解密的相关文档: 《用户数据解密说明文档》
4.在小程序后台配置好相应的后端请求地址,路径是:开发---->开发设置,如图
5.小程序如果需要做多个小程序的打通,还需要在微信开放平台绑定到开发者账号下面, 如果不需要union_id请忽略
6.服务端准备一个用户授权的接口,假设接口链接为http://test.dev.com/user/authorization,此接口接受如下参数
- code:微信登陆接口返回的登陆凭证,用户获取session_key
- iv:微信小程序登陆接口返回的向量,用于数据解密
- encrypted_data : 微信获取用户信息接口的返回的用户加密数据,用于后端的接口解析
- signature加密数据
接口返回的数据如下
{ "errcode": 200, "msg": "SUCCESS", "data": { "uid": 34098, "unionid": "xxx", } }
6.建表
1)用户表,其中比较重要的字段是union_id,因为我们是有多个小程序和公众号,因此使用这个来区分唯一的用户编号
DROP TABLE IF EXISTS `jz_wxa_user`; CREATE TABLE `jz_wxa_user` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `uid` bigint(18) DEFAULT NULL, `openid` varchar(255) CHARACTER SET utf8 DEFAULT NULL COMMENT 'openid', `user_name` varchar(100) CHARACTER SET utf8mb4 DEFAULT '', `nick_name` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '用户昵称', `sex` enum('0','1') CHARACTER SET utf8 DEFAULT '1' COMMENT '性别', `avatar` varchar(255) CHARACTER SET utf8 DEFAULT NULL COMMENT '用户头像', `province` varchar(100) CHARACTER SET utf8 DEFAULT NULL COMMENT '省份', `city` varchar(100) CHARACTER SET utf8 DEFAULT NULL COMMENT '城市', `country` varchar(100) CHARACTER SET utf8 DEFAULT NULL COMMENT '国家', `wx_union_id` varchar(255) CHARACTER SET utf8 DEFAULT NULL COMMENT '公众平台的唯一id', `from_url` varchar(255) CHARACTER SET utf8 DEFAULT NULL COMMENT '来源url', `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL, `from_appid` varchar(30) COLLATE utf8mb4_unicode_ci DEFAULT 'wx95fc895bebd3743b' COMMENT '来源appid', `wx_header` varchar(150) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '微信头像', `gh_openid` varchar(60) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '微信公众号openid', `phone` varchar(30) CHARACTER SET utf8 DEFAULT '' COMMENT '手机号码', PRIMARY KEY (`id`), KEY `idx_uid_union_id` (`uid`,`wx_union_id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
实现步骤
用户授权时序图
关键代码
小程序端
小程序端的获取用户信息流程
1)调用login方法获取code
2)调用getUserInfo方法获取用户的加密数据
3)调用后端的用户授权接口将用户信息保存到服务端
4)保存后端接口返回的uid和unionid到localstorage中,作为全局参数
获取用户的授权信息
getUid:function(cf){ var that = this wx.login({ success: function (ress) { var code = ress.code wx.getUserInfo({ withCredentials: true, success: function (res) { that.globalData.userInfo = res.userInfo; that.authorize(code, res.signature, res.iv, res.rawData, res.encryptedData, cf) } }) } }) }, authorize: function (code, signature, iv, rawData, encryptedData, cf) { var that =this var dataobj = { code: code, signature: signature, iv: iv, raw_data: rawData, encrypted_data: encryptedData } console.log("code:",code) var param = JSON.stringify(dataobj) param = that.Encrypt(param) var url = that.data.API_DOMAIN2 + "/user/authorization" + param wx.request({ url: url, method: "GET", header: { 'content-type': 'application/json' }, success: function (res) { if (res.data.errcode == 200) { wx.hideToast() wx.setStorage({ key: "uid", data: res.data.data.uid, success: function () { if (cf) { typeof cf == "function" && cf(res.data.data.uid) } } }) } else { that.exceptionHandle('uid', url, res.data.errcode, res.data.msg) } } }) },
服务端
入口方法
/** * api接口开发 * 获取详情的接口 * @param $uid 用户编号 * @param $iv 向量 * @param $encryptedData 微信加密的数据 * @param $rawData 判断是否为今天 * @param $signature 签名 * @return array */ public static function authorization($appid,$appsecret,$code,$iv,$encryptedData,$rawData,$signature){ $result = self::decodeWxData($appid,$appsecret,$code,$iv,$encryptedData); if($result['errcode'] != 200){ return $result; } //处理微信授权的逻辑 $wxUserData = $result['data']; error_log("authorization data=============>"); error_log(json_encode($wxUserData)); $uid = WxaUserService::regWxaUser($wxUserData); $data['uid'] = $uid['uid']; $data['unionid'] = $uid['unionid']; $result['data'] = $data; return $result; } /** * 解密微信的数据 * @param $code wx.login接口返回的code * @param $iv wx.getUserInfo接口或者wx.getWeRunData返回的iv * @param $encryptedData wx.getUserInfo接口或者wx.getWeRunData返回的加密数据 * @return array */ public static function decodeWxData($appid,$appsecret,$code,$iv,$encryptedData){ $sessionKeyUrl = sprintf('%s"htmlcode">/** * 保存用户信息的方法 * @param $wxaUserData * @param $regFromGh 表示是否从公众号进行注册 */ public function regWxaUser($wxaUserData,$regFromGh = false) { $value = $wxaUserData['unionId']; $key = getCacheKey('redis_key.cache_key.zset_list.lock') . $value; $newExpire = RedisHelper::getLock($key); $data = $this->storeWxaUser($wxaUserData,$regFromGh); RedisHelper::releaseLock($key, $newExpire); return $data; } /** * 保存信息 * @param $wxaUserData * @return mixed */ public function storeWxaUser($wxaUserData,$regFromGh = false) { $wxUnionId = $wxaUserData['unionId']; if (!$user = $this->getByWxUnionId($wxUnionId)) { $getAccountDataStartTime = time(); //这里是因为需要统一账户获取uid,所以这个是用户中心的接口,如果没有这个流程,则直接使用数据 if($accountData = AccountCenterHelper::regWxaUser($wxaUserData)){ $getAccountDataEndTime = time(); $accountRegTime = $getAccountDataEndTime - $getAccountDataStartTime; error_log("reg user spend time is ===================>" . $accountRegTime); $user = [ 'uid' => $accountData['uid'], 'user_name' => $accountData['user_name'], 'nick_name' => $wxaUserData['nickName'], 'sex' => $accountData['sex'], 'wx_union_id' => $accountData['wx_union_id'], 'avatar' => isset($accountData['avatar'])"", 'from_appid' => $accountData['from_appid'], 'province' => $wxaUserData['province'], 'city' => $wxaUserData['city'], 'country' => $wxaUserData['country'], 'openid' => $wxaUserData['openId'], 'wx_header' => isset($wxaUserData['avatarUrl'])"", 'gh_openid' => $regFromGh"", ]; error_log("insert data=============>" . json_encode($user)); $user = $this->store($user); $regApiUserEndTime = time(); error_log(" reg api user spend time================>" . ($regApiUserEndTime - $getAccountDataEndTime)); error_log(" after insert data=============>" . json_encode($user)); } }else{ if(!$user['wx_header']){ $updateData = [ 'id' => $user['id'], 'uid' => $user['uid'], 'wx_header' => $wxaUserData['avatarUrl'], ]; $this->update($updateData); } //同步用户的openid if($wxaUserData['openId'] != $user['openid']){ $updateData = [ 'id' => $user['id'], 'uid' => $user['uid'], 'openid' => $wxaUserData['openId'], ]; $this->update($updateData); } } $data['uid'] = $user['uid']; $data['unionid'] = $wxUnionId; return $data; }根据unionid获取用户信息
/** * 根据unionid获取用户信息 */ public function getByWxUnionId($unionId) { $cacheKey = getCacheKey('redis_key.cache_key.wxa_user.info') . $unionId; $value = $this->remember($cacheKey, function () use ($unionId) { $userInfo = WxaUser::where('wx_union_id', $unionId)->first(); $userInfo = $this->compactUserInfo($userInfo); return $userInfo; }); return $value; }WxBizDataHelper工具类
<"htmlcode"><"htmlcode"><"htmlcode"><?php /** * Created by PhpStorm. * User: Auser * Time: 10:33 */ namespace App\Http\Base\Wx; class ErrorCode { public static $OK = 0; public static $IllegalAesKey = -41001; public static $IllegalIv = -41002; public static $IllegalBuffer = -41003; public static $DecodeBase64Error = -41004; }以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
华山资源网 Design By www.eoogi.com
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
P70系列延期,华为新旗舰将在下月发布
3月20日消息,近期博主@数码闲聊站 透露,原定三月份发布的华为新旗舰P70系列延期发布,预计4月份上市。
而博主@定焦数码 爆料,华为的P70系列在定位上已经超过了Mate60,成为了重要的旗舰系列之一。它肩负着重返影像领域顶尖的使命。那么这次P70会带来哪些令人惊艳的创新呢?
根据目前爆料的消息来看,华为P70系列将推出三个版本,其中P70和P70 Pro采用了三角形的摄像头模组设计,而P70 Art则采用了与上一代P60 Art相似的不规则形状设计。这样的外观是否好看见仁见智,但辨识度绝对拉满。
更新日志
- 魔兽世界wlk暗牧一键输出宏是什么 wlk暗牧一键输出宏介绍
- 群星.1996-红不让台语原唱2辑【福和唱片】【WAV+CUE】
- 郭书瑶.2009-爱的抱抱(EP)【种子音乐】【FLAC分轨】
- 郑瑞芬.1989-BE.MY.BABY【现代】【WAV+CUE】
- 花钱请人每周放30万只不咬人的蚊子 防治登革热传播
- 饭制《第一后裔》丧尸版弗蕾娜
- 贝克汉姆亲临!2024FC品类游戏嘉年华圆满落幕
- 「命轨爻错之翼」风之翼发放说明
- 《原神》前瞻特别节目回顾长图
- 米游币抽抽乐-原神专场现已开启!
- 黑鸭子2001《风情中国HQCD》[日本版][WAV+CUE]
- 陈杰洲1990-成人礼[滚石][WAV+CUE]
- MarkAanderud-HandsFree(2024)[24-44,1]FLAC
- 孙露《观心》1:1母盘直刻限量版[低速原抓WAV+CUE][361M]
- 钟志刚《汽车DJ玩主》[低速原抓WAV+CUE][1G]