小程序登录设置

微信小程序的登录
// 展示本地存储能力

var logs = wx.getStorageSync('logs') || {};
logs.name = 'Tome';
logs.age = '28';
wx.setStorageSync('logs', logs);

一、小程序获取openid, session_key 1、获取code,有效期五分钟,只能使用一次 2、使用code获取openid, session_key, [unionid] wx.login({ success: res => { // 发送 res.code 到后台换取 openId, sessionKey, unionId console.log(res); wx.request({ url: 'http://localhost/mpserver/login.php', data: { code: res.code }, method: 'GET', success: function(res) { console.log(res.data) } }) } }) <!-- 如果只是展示用户头像昵称,可以使用 <open-data /> 组件 --> <open-data type="userAvatarUrl"></open-data> <open-data type="userNickName"></open-data> 二、获取用户详细信息:授权 1、已授权过 已授权:wx.getUserInfo() 当用户未授权过,调用该接口将直接进入fail回调 当用户授权过,可以使用该接口获取用户信息 现在的调用此接口没有弹框 app.js--------------------- onLoad: function() { // 查看是否授权 wx.getSetting({ success: function(res){ if (res.authSetting['scope.userInfo']) { // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框,不是实时更新的,大概是两小时 wx.getUserInfo({ withCredentials: false, success: function(res) { // 可以将 res 发送给后台解码出 unionId this.globalData.userInfo = res.userInfo; this.globalData.userInfo.openid = this.globalData.user.openid; this.globalData.userInfo.session_key = this.globalData.user.session_key; // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 if (this.userInfoReadyCallback) { this.userInfoReadyCallback(res) } } }) } } }) }, 注:当 withCredentials 为 true 时,要求此前有调用过 wx.login 且登录态尚未过期,此时返回的数据会包含 encryptedData, iv 等敏感信息;当 withCredentials 为 false 时,不要求有登录态,返回的数据不包含 encryptedData, iv 等敏感信息。 2、未授权:要求以按钮的形式告知用户去点击来授权 <button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button> <block wx:else> <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image> <text class="userinfo-nickname">{{userInfo.nickName}}</text> </block> login.js--------------------- Page({ data: { userInfo: {}, hasUserInfo: false, canIUse: wx.canIUse('button.open-type.getUserInfo') }, //事件处理函数 bindViewTap: function() { wx.navigateTo({ url: '../logs/logs' }) }, onLoad: function () { if (app.globalData.userInfo) { this.setData({ userInfo: app.globalData.userInfo, hasUserInfo: true }) } else if (this.data.canIUse){ // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 app.userInfoReadyCallback = res => { this.setData({ userInfo: res.userInfo, hasUserInfo: true }) } } else { // 在没有 open-type=getUserInfo 版本的兼容处理 wx.getUserInfo({ success: res => { app.globalData.userInfo = res.userInfo this.setData({ userInfo: res.userInfo, hasUserInfo: true }) } }) } }, // 授权并返回用户信息 getUserInfo: function(e) { console.log(e) app.globalData.userInfo = e.detail.userInfo this.setData({ userInfo: e.detail.userInfo, hasUserInfo: true }) } }) 返回: userInfo OBJECT 用户信息对象,不包含 openid 等敏感信息 rawData String 不包括敏感信息的原始数据字符串,用于计算签名。 signature String 使用 sha1( rawData + sessionkey ) 得到字符串,用于校验用户信息,参考文档 signature。 encryptedData String 包括敏感数据在内的完整用户信息的加密数据,详细见加密数据解密算法 iv String 加密算法的初始向量,详细见加密数据解密算法 userInfo包含信息: avatarUrl city country gender language nickName province 如果需要openid,unionid等信息,需要请求服务端解密encryptedData getUserInfo: function(e) { console.log(e); var self = this; wx.request({ url: 'http://localhost/mpserver/decrypt.php', data: { session_key: app.globalData.user.session_key, encrypted_data: e.detail.encryptedData, iv: e.detail.iv }, method: 'POST', header: { 'content-type': 'application/x-www-form-urlencoded' }, success: function(res) { console.log(res.data) app.globalData.userInfo = res.data self.setData({ userInfo: res.data, hasUserInfo: true }) } }) } 服务端: decrypt.php-------------------------------------------------------- <?php date_default_timezone_set('Asia/Shanghai'); header('Content-Type:application/json; charset=utf-8'); require_once('lib/wxBizDataCrypt.php'); $appid = 'wx89137bb28d7cd3e6'; $sessionKey = $_POST['session_key']; $encryptedData = $_POST['encrypted_data']; $iv = $_POST['iv']; $pc = new WXBizDataCrypt($appid, $sessionKey); $errCode = $pc->decryptData($encryptedData, $iv, $data ); if ($errCode == 0) { exit($data); } else { exit(json_encode(['status'=>false, 'errcode'=>$errCode])); } wxBizDataCrypt.php------------------------------------------------ <?php /** * 对微信小程序用户加密数据的解密示例代码. * * @copyright Copyright (c) 1998-2014 Tencent Inc. */ include_once "errorCode.php"; class WXBizDataCrypt { private $appid; private $sessionKey; /** * 构造函数 * @param $sessionKey string 用户在小程序登录后获取的会话密钥 * @param $appid string 小程序的appid */ public function __construct( $appid, $sessionKey) { $this->sessionKey = $sessionKey; $this->appid = $appid; } /** * 检验数据的真实性,并且获取解密后的明文. * @param $encryptedData string 加密的用户数据 * @param $iv string 与用户数据一同返回的初始向量 * @param $data string 解密后的原文 * * @return int 成功0,失败返回对应的错误码 */ public function decryptData( $encryptedData, $iv, &$data ) { if (strlen($this->sessionKey) != 24) { return ErrorCode::$IllegalAesKey; } $aesKey=base64_decode($this->sessionKey); if (strlen($iv) != 24) { return ErrorCode::$IllegalIv; } $aesIV=base64_decode($iv); $aesCipher=base64_decode($encryptedData); $result=openssl_decrypt( $aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV); $dataObj=json_decode( $result ); if( $dataObj == NULL ) { return ErrorCode::$IllegalBuffer; } if( $dataObj->watermark->appid != $this->appid ) { return ErrorCode::$IllegalBuffer; } $data = $result; return ErrorCode::$OK; } } errorCode.php------------------------------------------------------- class ErrorCode { public static $OK = 0; public static $IllegalAesKey = -41001; public static $IllegalIv = -41002; public static $IllegalBuffer = -41003; public static $DecodeBase64Error = -41004; } 解密后的信息: { "openId": "OPENID", "nickName": "NICKNAME", "gender": GENDER, "city": "CITY", "province": "PROVINCE", "country": "COUNTRY", "avatarUrl": "AVATARURL", "unionId": "UNIONID", "watermark": { "appid":"APPID", "timestamp":TIMESTAMP } } 总结: 1、应用初始化 wx.login() ---> code ---> 服务端得到openid,session_key,unionid绑定到本系统的用户信息user ---> 将user返回给小程序(过滤掉openid,session_key,unionid参数) ---> 将userid作为小程序和服务端通讯的标识。 2、如果已经授权过:wx.getUserInfo(),withCredentials: false,获取基本信息。 关于安全: 附加: 1、wx.request()方法说明,对于get,post方式有所不同,默认请求方式get data 数据说明: 最终发送给服务器的数据是 String 类型,如果传入的 data 不是 String 类型,会被转换成 String 。转换规则如下: 对于 GET 方法的数据,会将数据转换成 query string(encodeURIComponent(k)=encodeURIComponent(v)&encodeURIComponent(k)=encodeURIComponent(v)...) 对于 POST 方法且 header['content-type'] 为 application/json 的数据,会对数据进行 JSON 序列化,默认如此。 对于 POST 方法且 header['content-type'] 为 application/x-www-form-urlencoded 的数据,会将数据转换成 query string (encodeURIComponent(k)=encodeURIComponent(v)&encodeURIComponent(k)=encodeURIComponent(v)...) 因此对于POST请求我们应该设置 header: { 'content-type': 'application/x-www-form-urlencoded' }, 2、在wx.request()里面使用this表示该函数内部,如果想要设置值得话,需要换一个变量,在wx.request()外面 var self = this; 在wx.request()里面可以 self.globalData.user = res.data;来赋值,因为this是不存在globalData这个变量的,只有外部有这个变量。 3、关于session_key 开发者如果遇到因为session_key不正确而校验签名失败或解密失败,请关注下面几个与session_key有关的注意事项。 wx.login()调用时,用户的session_key会被更新而致使旧session_key失效。开发者应该在明确需要重新登录时才调用wx.login(),及时通过登录凭证校验接口更新服务器存储的session_key。 微信不会把session_key的有效期告知开发者。我们会根据用户使用小程序的行为对session_key进行续期。用户越频繁使用小程序,session_key有效期越长。 开发者在session_key失效时,可以通过重新执行登录流程获取有效的session_key。使用接口wx.checkSession()可以校验session_key是否有效,从而避免小程序反复执行登录流程。 当开发者在实现自定义登录态时,可以考虑以session_key有效期作为自身登录态有效期,也可以实现自定义的时效性策略。 --------------------- 原文:https://blog.csdn.net/raoxiaoya/article/details/97276131

  

posted @ 2019-08-01 14:02  蛋Mrs炒饭  阅读(1396)  评论(0编辑  收藏  举报