一,授權
1,首先在app.js裏檢測用戶是否授權
// 查看是否授權
wx.getSetting({
success: function (res) {
if (res.authSetting['scope.userInfo']) {
console.log('用戶已授權' + res.authSetting['scope.userInfo']);
}
else {
console.log('用戶未授權');
wx.navigateTo({
url: '../login/login'
})
}
}
})
2,沒有授權就跳到授權頁(單獨一個頁面,需要點擊open-type="getUserInfo"的按鈕)
<button class="cu-btn round shadow-blur lg bg-{{Theme}}" open-type="getUserInfo" lang="zh_CN" bindgetuserinfo="bindGetUserInfo">授權登錄</button>
3,拒絕授權或者授權失敗,就讓用戶停留在授權頁,成功則跳到首頁
bindGetUserInfo: function (e) {
if (e.detail.userInfo) {
//用戶按了允許授權按鈕
console.log('用戶按了允許授權按鈕');
var that = this;
wx.navigateTo({
url: '../index/index'
})
} else {
//用戶按了拒絕按鈕
wx.showModal({
title: '警告',
content: '您點擊了拒絕授權,將無法進入小程序,請授權之後再進入!!!',
showCancel: false,
confirmText: '返回授權',
success: function (res) {
if (res.confirm) {
console.log('用戶點擊了“返回授權”')
}
}
})
}
},
二,獲取用戶信息
1,獲取openid,用戶名,頭像等等
在點擊授權後,獲取用戶的信息,包括openid和unionid等等,發送給後臺註冊
wx: wx.getUserInfo({
withCredentials: true,//開啓獲取私密信息
success: function (res) {
//console.log('獲取成功:' + JSON.stringify(res))
var UserInfo = JSON.stringify(res);//放入 data{},post數據的key就是UserInfo
//發送加密數據UserInfo
})
},
fail: function (res) {
console.log('獲取unionid失敗(組件失敗)');
},
})
2,獲取手機號
官方文檔說明:
獲取微信用戶綁定的手機號,需先調用wx.login接口。 因爲需要用戶主動觸發才能發起獲取手機號接口,所以該功能不由 API
來調用,需用 button 組件的點擊來觸發。
注意:目前該接口針對非個人開發者,且完成了認證的小程序開放(不包含海外主體)。需謹慎使用,若用戶舉報較多或被發現在不必要場景下使用,微信有權永久回收該小程序的該接口權限。
使用方法 需要將 button 組件 open-type 的值設置爲 getPhoneNumber,當用戶點擊並同意之後,可以通過
bindgetphonenumber 事件回調獲取到微信服務器返回的加密數據, 然後在第三方服務端結合 session_key 以及
app_id 進行解密獲取手機號。 代碼示例 Page({ getPhoneNumber
(e) {
console.log(e.detail.errMsg)
console.log(e.detail.iv)
console.log(e.detail.encryptedData) } }) encryptedData String 包括敏感數據在內的完整用戶信息的加密數據,詳細見加密數據解密算法
iv String 加密算法的初始向量,詳細見加密數據解密算法 cloudID string 敏感數據對應的雲
ID,開通雲開發的小程序纔會返回,可通過雲調用直接獲取開放數據,詳細見雲調用直接獲取開放數據
三,註冊
主要是數據庫錄入openid,其他可看情況獲取,例如unionID,用戶名,頭像,手機等等
1,首先是post加密數據,放個獲取到的UserInfo例子
{“errMsg”:“getUserInfo:ok”,“rawData”:"{“nickName”:“R”,“gender”:1,“language”:“zh_CN”,“city”:"",“province”:“Bronkhorstspruit”,“country”:“South
Africa”,“avatarUrl”:“https://wx.qlogo.cn/mmopen/vi_32/DQHC3FoaN1TYicamwQaCPANedQBJj9DbNRy5BXeBEglTSJJfA/132”}",“userInfo”:{“nickName”:“R”,“gender”:1,“language”:“zh_CN”,“city”:"",“province”:“Bronkhorstspruit”,“country”:“South
Africa”,“avatarUrl”:“https://wx.qlogo.cn/mmopen/vi_32/DQHC3FoaN1TYicaoQBJj9DbNRy5BXeBEglTSJJfA/132”},“signature”:“ad4a2f5834d1eb9774503f90”,“encryptedData”:“oiWQJPHfxXBszs0HcpwnEuztq8jYbMWvu9AUir/QdSGvgW7HxGgXc0zAkPPTweCmTto0la+nCl5qgw5EUPYwltIrNEDTQolPDzny4ySKT2u1YFaRtzimfg37g+9Ho0q3gsPBy44ApaLdqeBvMLVit/JwJViPxLuEUwtkNUOuyccZGkrIx4pAQpLuE0bGsuSjceMcX8kf2CM7PfM4EFRANL3Zq3UyXSRV+hHgk4kXZ6KE7pjf9IuzA3iURqQ9nYHJR2wmFCSOvjt6G0Hn2vesg9EX1/4/PAY0jryvuxoKh12fYL59lw7chybRqGrn2b1uLnrxUI7htQBVLGwrtJvs+rrd0FX1PBF1sjSQ26/X8pXA43w+k1o1fFoRElw26vipdq3OTp9iIro=”,“iv”:“sWy22akgYteA==”}
2,解密開發數據
官方說明文檔解密開發數據
官方有各種後臺語言的示例代碼,貼一個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;
}
}
<?php
/**
* error code 說明.
* <ul>
* <li>-41001: encodingAesKey 非法</li>
* <li>-41003: aes 解密失敗</li>
* <li>-41004: 解密後得到的buffer非法</li>
* <li>-41005: base64加密失敗</li>
* <li>-41016: base64解密失敗</li>
* </ul>
*/
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
}
}
{
"phoneNumber": "13580006666",
"purePhoneNumber": "13580006666",
"countryCode": "86",
"watermark":
{
"appid":"APPID",
"timestamp": TIMESTAMP
}
}
四,登錄
官方說明文檔:登錄
function postCode() {
return new Promise(function (resolve) {
wx.login({
success: function (res) {
//console.log('code=' + res.code)
//發送請求
wx: wx.request({
url: 'login.php',
data: { code: res.code },
header: { 'content-type': 'application/x-www-form-urlencoded' },
method: 'POST',
dataType: 'json',
responseType: 'text',
success: function (res) {
console.log('登錄成功返回:' + res + JSON.stringify(res))
wx.setStorageSync('sid', res.data.msg)//把返回的(自定義登錄憑證=> sessionId\token) 存入本地
var newsid = res.data.msg;
resolve(newsid); //Promise成功後回調參數,相當於return。
},
fail: function (res) {
wx.showModal({
title: '溫馨提示',
content: res.data.error || '網絡繁忙,請稍後重試!',
showCancel: false,//關閉取消按鈕
})
},
complete: function (res) { },
})
}
})
})
}
//api接口
$api = "https://api.weixin.qq.com/sns/jscode2session?appid={$appid}&secret={$secret}&js_code={$code}&grant_type=authorization_code";
//獲取GET請求
function httpGet($url){
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 500);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, true);
curl_setopt($curl, CURLOPT_URL, $url);
$res = curl_exec($curl);
curl_close($curl);
if($res=='')
httpGet($url);
$str=json_decode($res);
//print_r($str);
return $str;
}
if($code!='')
{
$wxloginSttr=httpGet($api);//發送取得用戶信息
$openid = $wxloginSttr->openid;//發送取得openid
if($openid!='')
{
$onlycode='';//自定義加密,生成唯一session標識,返回給微信
$sql="";//檢查用戶是否存在
$sl=$db->query($sql);
$sl2=$sl->fetch();
////刪除用戶之前的session
unset($data);
$mdb->delete('wx_session',$data,0);
//錄入登錄session
unset($data);
$data["_id"]=$onlycode;
$data['session_key']=$wxloginSttr->session_key;
$data['syws_time']=time()+86400;//登陸有效期24小時
$data3=$mdb->insert('wx_session',$data);
if($data3==1)//insert==ok
{
$msg["msg"]=$onlycode;
}else
{
$msg["error"]="請重新登錄!!!!";
}
}else
{
$msg["error"]="請重新登錄!!!!!";
}
}else
{
$msg["error"]="非法登錄!";
}
echo json_encode($msg);
五,封裝request請求
官方說明文檔:request組件
header 中不能設置 Referer。
content-type 默認爲 application/json
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)…)
目前自己用的封裝比較簡單,有基礎功能,但還需不斷完善改進。
/* 封裝request-請求服務器
**含**傳遞和重獲session,統一處理session異常
**不含**攔截器和單獨處理其他異常
const util = require('../../utils/util.js')
util.requestUrl({
url: "接口路徑",
data:{},
method:"post",
success:function(res){
console.log(res)
},
header:'請求頭,可不填'
})
*/
function requestUrl({ url, data, method, success, header}) {
wx.showLoading({
title: '加載中',
})
let server = app.globalData.reURL;//正式域名
//請求頭可根據實際情況填寫
let header_type = header || { 'content-type': 'application/x-www-form-urlencoded', Authorization: wx.getStorageSync("sid") };
wx.request({
url: server + url,
data: data,
header: header_type,
method: method,
dataType: 'json',
responseType: 'text',
success: (res) => {
console.log(res.data);
if (登錄session==OK) {
wx.hideLoading();// 隱藏加載框
success(res)
}
else if (登錄session過期) {
//重新登錄
postCode().then(function (locationData) {
console.log('重新獲取的new-session-id:' + locationData)
//重新執行
requestUrl({
url,
data,
method,
success,
header
})
})
}
else {
wx.hideLoading();
//其他狀態判爲非法入侵,函數回饋提示後截斷在當頁
wx.showModal({
title: '溫馨提示',
content: res.data.error || '網絡繁忙,請稍後重試!',
showCancel: false,//關閉取消按鈕
})
}
},
fail: function (res) {
wx.hideLoading();
wx.showModal({
title: '溫馨提示',
content: res.data.error || '網絡繁忙,請稍後重試!',
showCancel: false,
})
},
complete: function () {
}
})
}