如何识别同一个小程序用户身份?
前端小程序代码参考:https://gitee.com/huiyani/wyymusicw
后端node完整代码:https://gitee.com/huiyani/wxminiprogramloginw
1、通过wx.login获取code;可写在app.js中的onLaunch钩子函数中
wx.login({
timeout: 1000,
success: res => {
const code = res.code
console.log(code)
// 拿到code发送给服务器
},
fail: err => {
console.log(err)
}
})
2、将code发送给我们的服务器;
wx.request({
url: 'http://47.99.199.25:3000/login',
method: 'post',
data: { code },
success: function(res) {
console.log(res);
},
fail: function(err){
console.log(err);
}
})
3、服务器拿到code请求微信接口获取openid和session_key;
// 使用到的npm库:axios、jsonwebtoken
exports.login = (req, res) => {
console.log("code:", req.body.code)
// 接口数据组装
const queryString = `appid=${config.appId}&secret=${config.appSecret}&js_code=${req.body.code}&grant_type=authorization_code`;
const wxAPI = `https://api.weixin.qq.com/sns/jscode2session?${queryString}`;
// 请求微信服务器
axios.get(wxAPI)
.then(response =>{
console.log("-----", response.data);
// 请求错误处理
if (response.data.errcode) {
return res.json(response.data)
}
// mongodb通过openid查user数据集
User.findOne({openId: response.data.openid}, (err, user) => {
// 数据库中已有此openid,从新生成token即可
if(user) {
return res.json({
openid: response.data.openid,
token: generateToken({openid: response.data.openid})
})
} else {
// 数据库中没有此openid
const user = new User();
user.openId = response.data.openid;
user.save();
return res.json({
openid: response.data.openid,
token: generateToken({openid: response.data.openid})
})
}
})
})
.catch(error => {
console.log(error)
})
}
// token生成函数
let generateToken = function(info) {
return jwt.sign(info, config.jwtSecret , {
expiresIn: 259200
})
}
// config
{
jwtSecret: 'myjwtsecret',
appId:'',
appSecret:''
}
4、服务器通过jwt生成token,token信息与 openid、session_key关联,返回token给用户;
5、用户拿到token后存到缓存中,后续在需要验证的接口传递token;
wx.setStorageSync('TOKEN_KEY', token)
需要从新获取token的情况
const token = wx.getStorageSync('TOKEN_KEY')
// token有没有过期
const checkResult = await checkToken()
// 判断session是否过期
const isSessionExpire = await checkSession()
if (!token || checkResult.errorCode || !isSessionExpire) {
this.loginAction()
}
判断session是否过期,调用wx接口
function checkSession() {
return new Promise((resolve) => {
wx.checkSession({
success: () => {
resolve(true)
},
fail: () => {
resolve(false)
}
})
})
}
后端token过期检查
exports.checkToken = (req, res) => {
let token = req.headers.token;
console.log(token);
if(token) {
console.log('token exist');
jwt.verify(token, config.jwtSecret, (err, decoded) => {
console.log('jwt.verify',decoded);
if(err) {
console.log('err');
if(err.name === 'TokenExpiredError') {
console.log('认证码失效,请重新登录!');
return res.status(401).json({ error: '认证码失效,请重新登录!', errorCode: 1003 }); // token过期
} else {
console.log('认证失败!');
return res.status(401).json({ error: '认证失败!', errorCode: 1002});
}
} else {
//if(decoded.openid) {
//req.openid = decoded.openid;
//console.log('req.openid = decoded.openid;');
return res.status(200).json({ message: '已登录'});
// } else {
// console.log('认证失败!');
//res.status(401).json({ error: '认证失败!', errorCode: 1004});
//}
}
});
} else {
console.log("no token");
return res.status(403).json({
error: '请提供认证码!',
errorCode: 1001 // 没有提供token
});
}
}
获取用户信息
小程序登录、用户信息相关接口调整说明 | 微信开放社区 (qq.com)
wxml
<button open-type="getUserInfo" bindtap="handleGetUser">授权信息</button>
js
handleGetUser: async function(event) {
const userInfo = await getUserInfo()
console.log(userInfo) // 点击允许能拿到用户信息
},
getUserInfo
export function getUserInfo() {
return new Promise((resolve, reject) => {
wx.getUserProfile({
desc: 'hi',
success: (res) => {
resolve(res)
},
fail: (err) => {
reject(err)
}
})
})
}
1
1
1
1
1
1
1
1
1
1