小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识,快速建立小程序内的用户体系。详情查看:
说明
之后开发者服务器可以根据用户标识来生成自定义登录态,用于后续业务逻辑中前后端交互时识别用户身份。
注意事项
session_key
是对用户数据进行 的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥。调用接口获取登录凭证(code)。通过凭证进而换取用户登录态信息,包括用户在当前小程序的唯一标识(openid)、微信开放平台帐号下的唯一标识(unionid,若当前小程序已绑定到微信开放平台帐号)及本次登录的会话密钥(session_key)等。用户数据的加解密通讯需要依赖会话密钥完成
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
timeout | number | 否 | 超时时间,单位ms | |
success | function | 否 | 接口调用成功的回调函数 | |
fail | function | 否 | 接口调用失败的回调函数 | |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
属性 | 类型 | 说明 |
---|---|---|
code | string | 用户登录凭证(有效期五分钟)。开发者需要在开发者服务器后台调用 ,使用 code 换取 openid、unionid、session_key 等信息 |
注意:这个作用于服务端,不要在客户端调用
登录凭证校验。通过 接口获得临时登录凭证 code 后传到开发者服务器调用此接口完成登录流程
GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
appid | string | 是 | 小程序 appId | |
secret | string | 是 | 小程序 appSecret | |
js_code | string | 是 | 登录时获取的 code | |
grant_type | string | 是 | 授权类型,此处只需填写 authorization_code |
属性 | 类型 | 说明 |
---|---|---|
openid | string | 用户唯一标识 |
session_key | string | 会话密钥 |
unionid | string | 用户在开放平台的唯一标识符,若当前小程序已绑定到微信开放平台帐号下会返回,详见 。 |
errcode | number | 错误码 |
errmsg | string | 错误信息 |
errcode 的合法值
值 | 说明 |
---|---|
-1 | 系统繁忙,此时请开发者稍候再试 |
0 | 请求成功 |
40029 | code 无效 |
45011 | 频率限制,每个用户每分钟100次 |
40226 | 高风险等级用户,小程序登录拦截 。风险等级详见 |
我真的是晕倒了,如果你使用的是云开发自带的数据库来存储的话,其实你是不需要获取openid的行为的,但是我一开始不知道呀,弄着弄着发现其实这个是有的,所以就分了两个了,一个是获取微信头像、昵称和openid的,一个是使用自带的获取手机号码的
工作步骤:
async getUserProfile(e) {
wx.getUserProfile({
desc: '用于获取用户个人信息',
success: function (detail) {
wx.login({
success: res => {
var code = res.code; //登录凭证
wx.cloud.callFunction({
name: "getCurrentUserInfo",
data: {
encryptedData: detail.encryptedData,
iv: detail.iv,
code: code,
userInfo: detail.rawData
}
}).then(res => {
console.log("res: ",res);
var openid = res.result.openid;
var status = res.result.status;
var phone = res.result.phone;
console.log("openid: ",openid);
console.log("status: ",status);
console.log("phone: ",phone);
console.log("nickName: ",detail.userInfo.nickName);
if(phone==undefined){
console.log("需要绑定手机号");
}else{
console.log("授权成功");
}
}).catch(res => {
console.log("res3: ",res);
})
}
});
},
fail: function () {
wx.showModal({
content: '取消授权将会影响相关服务,您确定取消授权吗?',
success (res) {
if (res.confirm) {
wx.showToast({
title: '已取消授权',
duration: 1500
})
} else if (res.cancel) {
this.getUserProfile()
}
}
})
}
})
}
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV
})
const db = cloud.database()
// 云函数入口函数
let user_id;
let user_uid;
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext()
let code = event.code;//获取小程序传来的code
let encryptedData = event.encryptedData;//获取小程序传来的encryptedData
let iv = event.iv;//获取小程序传来的iv
let userInfo = JSON.parse(event.userInfo) //获取个人信息
let appid = "xxxxxxxxx";//自己小程序后台管理的appid,可登录小程序后台查看
let secret = "xxxxxxxxx";//小程序后台管理的secret,可登录小程序后台查看
let grant_type = "authorization_code";// 授权(必填)默认值
let url = "https://api.weixin.qq.com/sns/jscode2session?grant_type="+grant_type+"&appid="+appid+"&secret="+secret+"&js_code="+code;
const stat = await new Promise((resolve, reject) => {
request(url, (err, response, body) => {
if (!err && response.statusCode == 200) {
let _data = JSON.parse(body)
let UserCount = 0;
user_id = _data.openid
user_uid = _data.unionid
db.collection('Account').where({
user_id: _data.openid // 填入当前用户 openid
}).count().then(res => {
UserCount = res.total;
if(UserCount == 0){/* 插入当前列表 */
db.collection('Account').add({
data: {
user_id: _data.openid,
nickName: userInfo.nickName,
avatarUrl: userInfo.avatarUrl,
gender: userInfo.gender,
phone: ''
}
})
.then(res => {
resolve("Insert success!");
})
.catch(res => {
reject("Insert fail!");
})
}else if(UserCount == 1){/* 更新当前列表 */
db.collection('Account').where({
user_id: _data.openid // 填入当前用户 openid
}).update({
data: {
nickName: userInfo.nickName,
avatarUrl: userInfo.avatarUrl,
gender: userInfo.gender
}
})
.then(res => {
resolve("Update success!");
}).catch(res => {
reject("Update fail!");
})
}else if(UserCount > 1){/* 删除所有此id的并且重新添加 */
db.collection('Account').where({
user_id: _data.openid // 填入当前用户 openid
}).remove()
.then(res => {
db.collection('Account').add({
data: {
user_id: _data.openid,
nickName: userInfo.nickName,
avatarUrl: userInfo.avatarUrl,
gender: userInfo.gender,
phone: ''
}
})
resolve("Remove and insert success!");
}).catch(res => {
reject("Remove fail!");
})
}
})
}
})
})
const CurrentPhoneObject = await db.collection('Account').where({
user_id: user_id // 填入当前用户 openid
}).get()
const CurrentPhone = CurrentPhoneObject.data[0].phone
console.log("CurrentPhone: ",CurrentPhone);
console.log("stat: ",stat);
console.log("user_id: ",user_id);
console.log("user_uid: ",user_uid);
return {
status: stat,
CurrentPhone: CurrentPhone,
openid: user_id,
unionid: user_uid
}
}
因为需要用户主动触发才能发起获取手机号接口,所以该功能不由 API 来调用,需用 组件的点击来触发。另外,新版本接口不再需要提前调用wx.login
进行登录。
<button type="primary" open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">获取手机号</button>
async getPhoneNumber(res) {
console.log(res)
const errMsg = res.detail.errMsg
if (errMsg != "getPhoneNumber:ok"){
wx.showToast({
title: '授权失败',
icon: 'error'
})
return
}
const cloudId = res.detail.cloudID
const cloudIdList = [cloudId]
wx.showLoading({
title: '获取中',
mask: true
})
const cloudFunRes = await wx.cloud.callFunction({
name: "getPhoneNumber",
data: {
cloudIdList
}
})
console.log("cloudFunRes: ",cloudFunRes)
const jsonStr = cloudFunRes.result.dataList[0].json
const jsonData = JSON.parse(jsonStr)
const phoneNumber = jsonData.data.phoneNumber
console.log(phoneNumber)
this.setData({
userPhone: phoneNumber
})
wx.hideLoading({
success: (res) => {},
})
},
const cloud = require('wx-server-sdk')
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV
})
// 云函数入口函数
exports.main = async (event) => {
const wxContext = cloud.getWXContext()
const openid = wxContext.OPENID
const appid = wxContext.APPID
const unionid = wxContext.UNIONID
const enc = wxContext.ENV
const cloudIdList = event.cloudIdList
try {
const result = await cloud.openapi.cloudbase.getOpenData({
openid: openid,
cloudidList: cloudIdList
})
const jsonStr = result.dataList[0].json
const jsonData = JSON.parse(jsonStr)
const phoneNumber = jsonData.data.phoneNumber
console.log("phoneNumber: ",phoneNumber)
return result
} catch (err) {
return err
}
}
主要代码来自博主: