前言
微信小程序API文檔:https://mp.weixin.qq.com/debug/wxadoc/dev/api/api-login.html
在實(shí)際的小程序開(kāi)發(fā)中癞揉,往往需要用戶授權(quán)登陸并獲取用戶的數(shù)據(jù)筐赔,快速對(duì)接用戶系統(tǒng)铣猩。
openId
: 用戶在當(dāng)前小程序的唯一標(biāo)識(shí)
unionId
: 如果開(kāi)發(fā)者擁有多個(gè)移動(dòng)應(yīng)用、網(wǎng)站應(yīng)用茴丰、和公眾帳號(hào)(包括小程序)达皿,可通過(guò)unionid來(lái)區(qū)分用戶的唯一性天吓,因?yàn)橹灰峭粋€(gè)微信開(kāi)放平臺(tái)帳號(hào)下的移動(dòng)應(yīng)用、網(wǎng)站應(yīng)用和公眾帳號(hào)(包括小程序)峦椰,用戶的unionid是唯一的失仁。換句話說(shuō),同一用戶们何,對(duì)同一個(gè)微信開(kāi)放平臺(tái)下的不同應(yīng)用萄焦,unionId是相同的。詳情登錄微信開(kāi)放平臺(tái)(open.weixin.qq.com) 冤竹。
在微信小程序開(kāi)發(fā)中拂封,unionId等敏感數(shù)據(jù)則被加密在encryptedData
,于是需要以下流程來(lái)解密敏感數(shù)據(jù)鹦蠕,從而獲取unionId等信息冒签。
流程
1、(客戶端)微信小程序客戶端調(diào)用 wx.login()接口獲取登錄憑證(code)
//1钟病、調(diào)用微信登錄接口萧恕,獲取code
wx.login({
success: function (r) {
var code = r.code;//登錄憑證
if (code) {
//2、調(diào)用獲取用戶信息接口
//...
} else {
console.log('獲取用戶登錄態(tài)失敵濉票唆!' + r.errMsg)
}
},
fail: function () {
callback(false)
}
})
2、(客戶端)微信小程序客戶端調(diào)用 wx.getUserInfo()接口獲取 用戶基本信息屹徘、encryptedData(用戶敏感信息加密數(shù)據(jù)) 和 iv(加密算法的初始向量 )
//1屯掖、調(diào)用微信登錄接口县袱,獲取code
wx.login({
success: function (r) {
var code = r.code;//登錄憑證
if (code) {
//2、調(diào)用獲取用戶信息接口
wx.getUserInfo({
success: function (res) {
console.log({encryptedData: res.encryptedData, iv: res.iv, code: code})
//3.解密用戶信息 獲取unionId
//...
},
fail: function () {
console.log('獲取用戶信息失敗')
}
})
} else {
console.log('獲取用戶登錄態(tài)失敹槌巍椎咧!' + r.errMsg)
}
},
fail: function () {
callback(false)
}
})
3倦始、(客戶端)將前面獲取到的 code 驰坊、encryptedData谊迄、iv發(fā)送到自己的服務(wù)器(開(kāi)發(fā)者服務(wù)器),通過(guò)自己的服務(wù)器(開(kāi)發(fā)者服務(wù)器)解密獲取信息
//1豆励、調(diào)用微信登錄接口夺荒,獲取code
wx.login({
success: function (r) {
var code = r.code;//登錄憑證
if (code) {
//2、調(diào)用獲取用戶信息接口
wx.getUserInfo({
success: function (res) {
console.log({encryptedData: res.encryptedData, iv: res.iv, code: code})
//3.請(qǐng)求自己的服務(wù)器肆糕,解密用戶信息 獲取unionId等加密信息
wx.request({
url: 'https://xxxx.com/wxsp/decodeUserInfo',//自己的服務(wù)接口地址
method: 'post',
header: {
'content-type': 'application/x-www-form-urlencoded'
},
data: {encryptedData: res.encryptedData, iv: res.iv, code: code},
success: function (data) {
//4.解密成功后 獲取自己服務(wù)器返回的結(jié)果
if (data.data.status == 1) {
var userInfo_ = data.data.userInfo;
console.log(userInfo_)
} else {
console.log('解密失敗')
}
},
fail: function () {
console.log('系統(tǒng)錯(cuò)誤')
}
})
},
fail: function () {
console.log('獲取用戶信息失敗')
}
})
} else {
console.log('獲取用戶登錄態(tài)失敯愣选在孝!' + r.errMsg)
}
},
fail: function () {
console.log('登陸失敗')
}
})
4诚啃、(服務(wù)端 php)自己的服務(wù)器發(fā)送code到微信服務(wù)器獲取openid(用戶唯一標(biāo)識(shí))和session_key(會(huì)話密鑰),最后將encryptedData私沮、iv始赎、session_key通過(guò)AES解密獲取到用戶敏感數(shù)據(jù)
解密需要 引用的文件官網(wǎng)可以下載
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html
/**
* 解密用戶敏感數(shù)據(jù)
*
* @param encryptedData 明文,加密數(shù)據(jù)
* @param iv 加密算法的初始向量
* @param code 用戶允許登錄后,回調(diào)內(nèi)容會(huì)帶上 code(有效期五分鐘),開(kāi)發(fā)者需要將 code 發(fā)送到開(kāi)發(fā)者服務(wù)器后臺(tái)造垛,使用code 換取 session_key api魔招,將 code 換成 openid 和 session_key
* @return
*/
$code = input('get.code');
$appid = 'wx8c9d056ead85efd7';
$secret = '849fbc7dff5c949c2a9707d9a20df7a8';
$encryptedData = input('encryptedData');
$iv = input('iv');
if($code != ''){
$url = 'https://api.weixin.qq.com/sns/jscode2session?appid='.$appid.'&secret='.$secret.'&js_code='.$code.'&grant_type=authorization_code';
$html = file_get_contents($url);
$obj = json_decode($html);
if(isset($obj->errcode)){
// 獲取用戶信息失敗
return $html;
}else{
$arrlist['openid'] = $obj->openid;
$arrlist['session_key'] = $obj->session_key;
/**
* 解密用戶敏感數(shù)據(jù)
*
* @param encryptedData 明文,加密數(shù)據(jù)
* @param iv 加密算法的初始向量
* @param code 用戶允許登錄后,回調(diào)內(nèi)容會(huì)帶上 code(有效期五分鐘)五辽,開(kāi)發(fā)者需要將 code 發(fā)送到開(kāi)發(fā)者服務(wù)器后臺(tái)办斑,使用code 換取 session_key api,將 code 換成 openid 和 session_key
* @return
*/
include_once "wxBizDataCrypt.php";
$pc = new \WXBizDataCrypt( $appid, $arrlist['session_key']);
$errCode = $pc->decryptData($encryptedData, $iv, $data );
$data = json_decode($data);//$data 包含用戶所有基本信息
$arrlist['time'] = time();
$arrlist['city'] = $data->city;//城市-市
$arrlist['country'] = $data->country;//國(guó)家
$arrlist['gender'] = $data->gender;//性別
$arrlist['language'] = $data->language;//語(yǔ)言
$arrlist['nickName'] = $data->nickName;//昵稱
$arrlist['avatarUrl'] = $data->avatarUrl;//頭像
$arrlist['province'] = $data->province;//城市-省份
//判斷獲取信息是否成功
if ($errCode != 0) {
return $errCode;
}
//存入數(shù)據(jù)庫(kù)
$user = db('xw_userinfo');
//判斷是否已存在
$list = $user->where('openid',$arrlist['openid'])->find();
if(empty($list)){
//數(shù)據(jù)不存在 則存入數(shù)據(jù)
$user->insert($arrlist);
}else{
//數(shù)據(jù)存在 則更新數(shù)據(jù)
$where['openid'] = $arrlist['openid'];
$user->where($where)->update($arrlist);
}
return $html;
}
}else{
return json_encode('code為空');
}
總結(jié)
好了杆逗,總算完成數(shù)據(jù)解密了
qq:1366860941