让我们先来看看整个小程序登录的过程
wx.login()
获取 临时登录凭证 code
wx.getUserInfo()
获取 encryotedData
和 iv
openId
和 session_key
需要传输的信息有 7 个参数
appid 小程序唯一标识符
secret 小程序的app secret
// 以上两个可以通过这里获取:https://mp.weixin.qq.com/wxopen/devprofile?action=get_profile&token=991932229&lang=zh_CN
js_code //wx.login登录时获取的临时登录凭证 code,用于后续获取session_key
// 下面两个参数,是给服务器签名和效验用户信息的
signature 使用 sha1( rawData + sessionKey ) 得到的字符串,用于效验用户信息。
rawData 不包括敏感信息的原始数据字符串,用于计算签名。
// 下面两个参数是用于解密 openId 和 UnionId 的
encryptedData 包含敏感数据在内的完整用户信息
vi 加密算法的初始化向量
当然可以精简为 3 个参数
签名效验的参数可以省略,appid 和 secret 可以直接写在后端服务器上
js_code // 用户给后端获取 session_key
encryptedData // 包含敏感数据的用户完整信息的加密数据
vi //加密算法的初始化向量
实现代码
const app = getApp()
// 登录
function login () {
wx.login({
success: e => {
let code = e.code // 获取临时登录凭证
wx.getUserInfo({
success: res => {
let { encryptedData, vi } = res // 获取给后端解密参数
thirdLogin(code, encryptedData, vi)
}
})
}
})
}
function thirdLogin (code, encryptedData, vi) {
// 给后端发送请求获取 session_key
res.request({
url: '后端服务器接口',
data: {
code,
encryptedData,
vi
},
success: res => {
let thirdSessionId = res.data.data.thirdSessionId
app.globalData.thirdSessionId = thirdSessionId // 获取 session_key
wx.setStorageSync('thirdSessionId', thirdSessionId)
}
})
}
js_code
去微信服务器拿到 session_key
sha1
( rawData
+ sessionKey
),拿到字符串,判断与 signature
值是否相同,如果相同则用户信息无误,可进行下一步.如果不同,则说明用户信息被篡改或过期。appId
, sessionKey
, encryptedData
, iv
,返回一个jsonObj),拿到 openId
和 unionId
等信息,执行服务器端的注册/登录操作.thirdSessionId
(或其他token),以及用户信息返回给客户端.其中,服务器去获取session_key的请求地址为:
(小写为固定写好的,大写为待替换的)
https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
返回:
//正常返回的JSON数据包
{
"openid": "OPENID",
"session_key": "SESSIONKEY"
"expires_in": 2592000
}
//错误时返回JSON数据包(示例为Code无效)
{
"errcode": 40029,
"errmsg": "invalid code"
}
相关解密算法:
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html
注意:示例代码中有node,c++,php,python的,没有java的.
Java 解密可参考这篇文章,写的很棒:http://www.cnblogs.com/nosqlcoco/p/6105749.html
需要服务器返回的信息:
thirdSessionId/token 登录状态标识
userInfo: jsonObject,用户在我们平台上的信息,其内容与getPersonalInfo接口返回的相同。
unionId // 注意:如果你的小程序没有绑定微信开放平台,解密的数据中不包含unionid参数
关于 unionId 的介绍可参考这篇文章:https://blog.csdn.net/linsongbin1/article/details/79685609