以上是登录流程图

 

说明:

  1. 调用 wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。
  2. 调用 code2Session 接口,换取 用户唯一标识 OpenID 和 会话密钥 session_key。
  3. 调用 code2Session 接口拿到OpenID 去获取token接口,根据openid 换取token
  4. 小程序请求登录区内接口,通过wx.checkSession检查登录态,如果失效重新走上述登录流程
  5. 根据需求:拿到token存储在缓存中,并存储远程用户信息

之后开发者服务器可以根据用户标识来生成自定义登录态,用于后续业务逻辑中前后端交互时识别用户身份。

注意:

  1. 会话密钥 session_key 是对用户数据进行 加密签名 的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥。
  2. 临时登录凭证 code 只能使用一次

代码部分

wxutil.js 文件
/**
* Promise化小程序接口 JJ
*/

class WxUtil {
constructor() {

}

/**
* 初始化登陆
*/
initlogin() {
let {login, code2session, getToken, storeUserinfo} = this;
wx.checkSession({
success() {
//session_key 未过期,并且在本生命周期一直有效
let openid = wx.getStorageSync("openid")
if (openid) {
console.log("session_key未过期 本地有openind 重新获取token");
getToken(openid).then(storeUserinfo).then(e => console.log(e)).catch(e => console.log(e));
} else {
console.log("本地无openid 重新获取token");
login().then(code2session).then(getToken).then(storeUserinfo).then(r => console.log("token写入本地", r)).catch(e => console.log(e));
}

},
fail() {
// session_key 已经失效,需要重新执行登录流程
console.log("session_key过期 重新获取token");
login().then(code2session).then(getToken).then(storeUserinfo).then(r => console.log("token写入本地", r)).catch(e => console.log(e));
}
});


};

/**
* 登陆
*/
login() {
return new Promise((resolve, reject) => wx.login({success: resolve, fail: reject}));
};


/**
* 获取openid server 有调用限制
*/
code2session(code) {
return new Promise((resolve, reject) =>
wx.request({
url: getApp().config.url + 'miniprogram/wxmp/code2session',
data: {
code: code.code
},
header: {
'content-type': 'application/json' // 默认值
},
success(res) {
if (res.statusCode === 200) {
var openid = res.data.data.openid;
if (openid) {
wx.setStorageSync("openid", res.data.data.openid);
resolve(res.data.data.openid)
}
}
reject(res.data);
}
}))
};

/**
* 根据openid 换取token
*/
getToken(openid) {
console.log("openid:" + openid);
return new Promise((resolve, reject) =>
wx.request({
url: getApp().config.url + 'auth/openid/token',
data: {
openid: openid
},
method: 'POST',
header: {
"Content-Type": "application/x-www-form-urlencoded",
'Authorization': 'Basic YXBwOmFwcA==' // 默认值
},
success(res) {
if (res.data.access_token) {
getApp().onFire.fire("loginSucess");
let tokenObj = res.data;
tokenObj.createTime = new Date().getTime()/1000;
wx.setStorageSync("tokenObj",tokenObj);
resolve(res.data);
} else {
reject(res.data);
}
}
}))
}

/**
* 刷新TOKEN todo
*/
refresToken() {
return new Promise((resolve, reject) => wx.getUserInfo({success: resolve, fail: reject}));
};

/**
* 存储远程用户信息
*/
storeUserinfo(token) {
console.log("token", token)
return new Promise((resolve, reject) =>
wx.request({
url: getApp().config.url + 'admin/user/info',
data: {},
method: 'GET',
header: {
'content-type': 'application/json', // 默认值
'Authorization': `Bearer ${token.access_token}`
},
success(res) {
console.log("useinfo resdata.data");
wx.setStorageSync("userinfo", res.data.data);
}
}))
}

/**
* 获取用户信息
*/
getUserInfo() {
return new Promise((resolve, reject) => wx.getUserInfo({success: resolve, fail: reject}));
};


/**
* 检测用户状态
*/
checkSession() {
return new Promise((resolve, reject) => wx.checkSession({success: resolve, fail: reject}));
};
 
}

export default WxUtil    
 
app.js  文件
// 接口函数的调用
 
onShow (options) {
// token 过期情况p判断
let {getToken,storeUserinfo} = this.wxutil;
let tokenObj = wx.getStorageSync("tokenObj");
let openid = wx.getStorageSync("openid");
if(tokenObj && openid){
let {createTime,expires_in} = tokenObj;
let isFetchToken = (createTime+expires_in) < (new Date().getTime()/1000 -1000)
if(isFetchToken){
getToken(openid).then(storeUserinfo).then(r=>console.log(r))
}
}

},