小程序登录设置
微信小程序的登錄
// 展示本地存儲(chǔ)能力
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 => {// 發(fā)送 res.code 到后臺(tái)換取 openId, sessionKey, unionIdconsole.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>二、獲取用戶詳細(xì)信息:授權(quán)1、已授權(quán)過(guò)已授權(quán):wx.getUserInfo()當(dāng)用戶未授權(quán)過(guò),調(diào)用該接口將直接進(jìn)入fail回調(diào)當(dāng)用戶授權(quán)過(guò),可以使用該接口獲取用戶信息現(xiàn)在的調(diào)用此接口沒(méi)有彈框app.js---------------------onLoad: function() {// 查看是否授權(quán)wx.getSetting({success: function(res){if (res.authSetting['scope.userInfo']) {// 已經(jīng)授權(quán),可以直接調(diào)用 getUserInfo 獲取頭像昵稱,不會(huì)彈框,不是實(shí)時(shí)更新的,大概是兩小時(shí)wx.getUserInfo({withCredentials: false,success: function(res) {// 可以將 res 發(fā)送給后臺(tái)解碼出 unionIdthis.globalData.userInfo = res.userInfo;this.globalData.userInfo.openid = this.globalData.user.openid;this.globalData.userInfo.session_key = this.globalData.user.session_key;// 由于 getUserInfo 是網(wǎng)絡(luò)請(qǐng)求,可能會(huì)在 Page.onLoad 之后才返回// 所以此處加入 callback 以防止這種情況if (this.userInfoReadyCallback) {this.userInfoReadyCallback(res)}}})}}})},注:當(dāng) withCredentials 為 true 時(shí),要求此前有調(diào)用過(guò) wx.login 且登錄態(tài)尚未過(guò)期,此時(shí)返回的數(shù)據(jù)會(huì)包含 encryptedData, iv 等敏感信息;當(dāng) withCredentials 為 false 時(shí),不要求有登錄態(tài),返回的數(shù)據(jù)不包含 encryptedData, iv 等敏感信息。2、未授權(quán):要求以按鈕的形式告知用戶去點(diǎn)擊來(lái)授權(quán)<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')},//事件處理函數(shù)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 是網(wǎng)絡(luò)請(qǐng)求,可能會(huì)在 Page.onLoad 之后才返回// 所以此處加入 callback 以防止這種情況app.userInfoReadyCallback = res => {this.setData({userInfo: res.userInfo,hasUserInfo: true})}} else {// 在沒(méi)有 open-type=getUserInfo 版本的兼容處理wx.getUserInfo({success: res => {app.globalData.userInfo = res.userInfothis.setData({userInfo: res.userInfo,hasUserInfo: true})}})}},// 授權(quán)并返回用戶信息getUserInfo: function(e) {console.log(e)app.globalData.userInfo = e.detail.userInfothis.setData({userInfo: e.detail.userInfo,hasUserInfo: true})}})返回:userInfo OBJECT 用戶信息對(duì)象,不包含 openid 等敏感信息rawData String 不包括敏感信息的原始數(shù)據(jù)字符串,用于計(jì)算簽名。signature String 使用 sha1( rawData + sessionkey ) 得到字符串,用于校驗(yàn)用戶信息,參考文檔 signature。encryptedData String 包括敏感數(shù)據(jù)在內(nèi)的完整用戶信息的加密數(shù)據(jù),詳細(xì)見加密數(shù)據(jù)解密算法iv String 加密算法的初始向量,詳細(xì)見加密數(shù)據(jù)解密算法userInfo包含信息:avatarUrlcitycountrygenderlanguagenickNameprovince如果需要openid,unionid等信息,需要請(qǐng)求服務(wù)端解密encryptedDatagetUserInfo: 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.dataself.setData({userInfo: res.data,hasUserInfo: true})}})}服務(wù)端:decrypt.php--------------------------------------------------------<?phpdate_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/*** 對(duì)微信小程序用戶加密數(shù)據(jù)的解密示例代碼.** @copyright Copyright (c) 1998-2014 Tencent Inc.*/include_once "errorCode.php";class WXBizDataCrypt{private $appid;private $sessionKey;/*** 構(gòu)造函數(shù)* @param $sessionKey string 用戶在小程序登錄后獲取的會(huì)話密鑰* @param $appid string 小程序的appid*/public function __construct( $appid, $sessionKey){$this->sessionKey = $sessionKey;$this->appid = $appid;}/*** 檢驗(yàn)數(shù)據(jù)的真實(shí)性,并且獲取解密后的明文.* @param $encryptedData string 加密的用戶數(shù)據(jù)* @param $iv string 與用戶數(shù)據(jù)一同返回的初始向量* @param $data string 解密后的原文** @return int 成功0,失敗返回對(duì)應(yīng)的錯(cuò)誤碼*/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}}總結(jié): 1、應(yīng)用初始化 wx.login() ---> code ---> 服務(wù)端得到openid,session_key,unionid綁定到本系統(tǒng)的用戶信息user ---> 將user返回給小程序(過(guò)濾掉openid,session_key,unionid參數(shù)) ---> 將userid作為小程序和服務(wù)端通訊的標(biāo)識(shí)。 2、如果已經(jīng)授權(quán)過(guò):wx.getUserInfo(),withCredentials: false,獲取基本信息。關(guān)于安全:附加: 1、wx.request()方法說(shuō)明,對(duì)于get,post方式有所不同,默認(rèn)請(qǐng)求方式getdata 數(shù)據(jù)說(shuō)明:最終發(fā)送給服務(wù)器的數(shù)據(jù)是 String 類型,如果傳入的 data 不是 String 類型,會(huì)被轉(zhuǎn)換成 String 。轉(zhuǎn)換規(guī)則如下:對(duì)于 GET 方法的數(shù)據(jù),會(huì)將數(shù)據(jù)轉(zhuǎn)換成 query string(encodeURIComponent(k)=encodeURIComponent(v)&encodeURIComponent(k)=encodeURIComponent(v)...)對(duì)于 POST 方法且 header['content-type'] 為 application/json 的數(shù)據(jù),會(huì)對(duì)數(shù)據(jù)進(jìn)行 JSON 序列化,默認(rèn)如此。對(duì)于 POST 方法且 header['content-type'] 為 application/x-www-form-urlencoded 的數(shù)據(jù),會(huì)將數(shù)據(jù)轉(zhuǎn)換成 query string (encodeURIComponent(k)=encodeURIComponent(v)&encodeURIComponent(k)=encodeURIComponent(v)...)因此對(duì)于POST請(qǐng)求我們應(yīng)該設(shè)置header: {'content-type': 'application/x-www-form-urlencoded'},2、在wx.request()里面使用this表示該函數(shù)內(nèi)部,如果想要設(shè)置值得話,需要換一個(gè)變量,在wx.request()外面 var self = this; 在wx.request()里面可以 self.globalData.user = res.data;來(lái)賦值,因?yàn)閠his是不存在globalData這個(gè)變量的,只有外部有這個(gè)變量。3、關(guān)于session_key 開發(fā)者如果遇到因?yàn)閟ession_key不正確而校驗(yàn)簽名失敗或解密失敗,請(qǐng)關(guān)注下面幾個(gè)與session_key有關(guān)的注意事項(xiàng)。wx.login()調(diào)用時(shí),用戶的session_key會(huì)被更新而致使舊session_key失效。開發(fā)者應(yīng)該在明確需要重新登錄時(shí)才調(diào)用wx.login(),及時(shí)通過(guò)登錄憑證校驗(yàn)接口更新服務(wù)器存儲(chǔ)的session_key。微信不會(huì)把session_key的有效期告知開發(fā)者。我們會(huì)根據(jù)用戶使用小程序的行為對(duì)session_key進(jìn)行續(xù)期。用戶越頻繁使用小程序,session_key有效期越長(zhǎng)。開發(fā)者在session_key失效時(shí),可以通過(guò)重新執(zhí)行登錄流程獲取有效的session_key。使用接口wx.checkSession()可以校驗(yàn)session_key是否有效,從而避免小程序反復(fù)執(zhí)行登錄流程。當(dāng)開發(fā)者在實(shí)現(xiàn)自定義登錄態(tài)時(shí),可以考慮以session_key有效期作為自身登錄態(tài)有效期,也可以實(shí)現(xiàn)自定義的時(shí)效性策略。 --------------------- 原文:https://blog.csdn.net/raoxiaoya/article/details/97276131
// 展示本地存儲(chǔ)能力
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 => {// 發(fā)送 res.code 到后臺(tái)換取 openId, sessionKey, unionIdconsole.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>二、獲取用戶詳細(xì)信息:授權(quán)1、已授權(quán)過(guò)已授權(quán):wx.getUserInfo()當(dāng)用戶未授權(quán)過(guò),調(diào)用該接口將直接進(jìn)入fail回調(diào)當(dāng)用戶授權(quán)過(guò),可以使用該接口獲取用戶信息現(xiàn)在的調(diào)用此接口沒(méi)有彈框app.js---------------------onLoad: function() {// 查看是否授權(quán)wx.getSetting({success: function(res){if (res.authSetting['scope.userInfo']) {// 已經(jīng)授權(quán),可以直接調(diào)用 getUserInfo 獲取頭像昵稱,不會(huì)彈框,不是實(shí)時(shí)更新的,大概是兩小時(shí)wx.getUserInfo({withCredentials: false,success: function(res) {// 可以將 res 發(fā)送給后臺(tái)解碼出 unionIdthis.globalData.userInfo = res.userInfo;this.globalData.userInfo.openid = this.globalData.user.openid;this.globalData.userInfo.session_key = this.globalData.user.session_key;// 由于 getUserInfo 是網(wǎng)絡(luò)請(qǐng)求,可能會(huì)在 Page.onLoad 之后才返回// 所以此處加入 callback 以防止這種情況if (this.userInfoReadyCallback) {this.userInfoReadyCallback(res)}}})}}})},注:當(dāng) withCredentials 為 true 時(shí),要求此前有調(diào)用過(guò) wx.login 且登錄態(tài)尚未過(guò)期,此時(shí)返回的數(shù)據(jù)會(huì)包含 encryptedData, iv 等敏感信息;當(dāng) withCredentials 為 false 時(shí),不要求有登錄態(tài),返回的數(shù)據(jù)不包含 encryptedData, iv 等敏感信息。2、未授權(quán):要求以按鈕的形式告知用戶去點(diǎn)擊來(lái)授權(quán)<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')},//事件處理函數(shù)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 是網(wǎng)絡(luò)請(qǐng)求,可能會(huì)在 Page.onLoad 之后才返回// 所以此處加入 callback 以防止這種情況app.userInfoReadyCallback = res => {this.setData({userInfo: res.userInfo,hasUserInfo: true})}} else {// 在沒(méi)有 open-type=getUserInfo 版本的兼容處理wx.getUserInfo({success: res => {app.globalData.userInfo = res.userInfothis.setData({userInfo: res.userInfo,hasUserInfo: true})}})}},// 授權(quán)并返回用戶信息getUserInfo: function(e) {console.log(e)app.globalData.userInfo = e.detail.userInfothis.setData({userInfo: e.detail.userInfo,hasUserInfo: true})}})返回:userInfo OBJECT 用戶信息對(duì)象,不包含 openid 等敏感信息rawData String 不包括敏感信息的原始數(shù)據(jù)字符串,用于計(jì)算簽名。signature String 使用 sha1( rawData + sessionkey ) 得到字符串,用于校驗(yàn)用戶信息,參考文檔 signature。encryptedData String 包括敏感數(shù)據(jù)在內(nèi)的完整用戶信息的加密數(shù)據(jù),詳細(xì)見加密數(shù)據(jù)解密算法iv String 加密算法的初始向量,詳細(xì)見加密數(shù)據(jù)解密算法userInfo包含信息:avatarUrlcitycountrygenderlanguagenickNameprovince如果需要openid,unionid等信息,需要請(qǐng)求服務(wù)端解密encryptedDatagetUserInfo: 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.dataself.setData({userInfo: res.data,hasUserInfo: true})}})}服務(wù)端:decrypt.php--------------------------------------------------------<?phpdate_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/*** 對(duì)微信小程序用戶加密數(shù)據(jù)的解密示例代碼.** @copyright Copyright (c) 1998-2014 Tencent Inc.*/include_once "errorCode.php";class WXBizDataCrypt{private $appid;private $sessionKey;/*** 構(gòu)造函數(shù)* @param $sessionKey string 用戶在小程序登錄后獲取的會(huì)話密鑰* @param $appid string 小程序的appid*/public function __construct( $appid, $sessionKey){$this->sessionKey = $sessionKey;$this->appid = $appid;}/*** 檢驗(yàn)數(shù)據(jù)的真實(shí)性,并且獲取解密后的明文.* @param $encryptedData string 加密的用戶數(shù)據(jù)* @param $iv string 與用戶數(shù)據(jù)一同返回的初始向量* @param $data string 解密后的原文** @return int 成功0,失敗返回對(duì)應(yīng)的錯(cuò)誤碼*/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}}總結(jié): 1、應(yīng)用初始化 wx.login() ---> code ---> 服務(wù)端得到openid,session_key,unionid綁定到本系統(tǒng)的用戶信息user ---> 將user返回給小程序(過(guò)濾掉openid,session_key,unionid參數(shù)) ---> 將userid作為小程序和服務(wù)端通訊的標(biāo)識(shí)。 2、如果已經(jīng)授權(quán)過(guò):wx.getUserInfo(),withCredentials: false,獲取基本信息。關(guān)于安全:附加: 1、wx.request()方法說(shuō)明,對(duì)于get,post方式有所不同,默認(rèn)請(qǐng)求方式getdata 數(shù)據(jù)說(shuō)明:最終發(fā)送給服務(wù)器的數(shù)據(jù)是 String 類型,如果傳入的 data 不是 String 類型,會(huì)被轉(zhuǎn)換成 String 。轉(zhuǎn)換規(guī)則如下:對(duì)于 GET 方法的數(shù)據(jù),會(huì)將數(shù)據(jù)轉(zhuǎn)換成 query string(encodeURIComponent(k)=encodeURIComponent(v)&encodeURIComponent(k)=encodeURIComponent(v)...)對(duì)于 POST 方法且 header['content-type'] 為 application/json 的數(shù)據(jù),會(huì)對(duì)數(shù)據(jù)進(jìn)行 JSON 序列化,默認(rèn)如此。對(duì)于 POST 方法且 header['content-type'] 為 application/x-www-form-urlencoded 的數(shù)據(jù),會(huì)將數(shù)據(jù)轉(zhuǎn)換成 query string (encodeURIComponent(k)=encodeURIComponent(v)&encodeURIComponent(k)=encodeURIComponent(v)...)因此對(duì)于POST請(qǐng)求我們應(yīng)該設(shè)置header: {'content-type': 'application/x-www-form-urlencoded'},2、在wx.request()里面使用this表示該函數(shù)內(nèi)部,如果想要設(shè)置值得話,需要換一個(gè)變量,在wx.request()外面 var self = this; 在wx.request()里面可以 self.globalData.user = res.data;來(lái)賦值,因?yàn)閠his是不存在globalData這個(gè)變量的,只有外部有這個(gè)變量。3、關(guān)于session_key 開發(fā)者如果遇到因?yàn)閟ession_key不正確而校驗(yàn)簽名失敗或解密失敗,請(qǐng)關(guān)注下面幾個(gè)與session_key有關(guān)的注意事項(xiàng)。wx.login()調(diào)用時(shí),用戶的session_key會(huì)被更新而致使舊session_key失效。開發(fā)者應(yīng)該在明確需要重新登錄時(shí)才調(diào)用wx.login(),及時(shí)通過(guò)登錄憑證校驗(yàn)接口更新服務(wù)器存儲(chǔ)的session_key。微信不會(huì)把session_key的有效期告知開發(fā)者。我們會(huì)根據(jù)用戶使用小程序的行為對(duì)session_key進(jìn)行續(xù)期。用戶越頻繁使用小程序,session_key有效期越長(zhǎng)。開發(fā)者在session_key失效時(shí),可以通過(guò)重新執(zhí)行登錄流程獲取有效的session_key。使用接口wx.checkSession()可以校驗(yàn)session_key是否有效,從而避免小程序反復(fù)執(zhí)行登錄流程。當(dāng)開發(fā)者在實(shí)現(xiàn)自定義登錄態(tài)時(shí),可以考慮以session_key有效期作為自身登錄態(tài)有效期,也可以實(shí)現(xiàn)自定義的時(shí)效性策略。 --------------------- 原文:https://blog.csdn.net/raoxiaoya/article/details/97276131
轉(zhuǎn)載于:https://www.cnblogs.com/ws-zhangbo/p/11282076.html
總結(jié)
- 上一篇: java之spring mvc之文件上传
- 下一篇: 自动驾驶中高精地图的大规模生产:视觉惯导