下面是详细讲解微信小程序后端无法保持session的原因及解决办法的攻略。
问题描述
在使用微信小程序开发时,我们经常需要与后端服务器进行交互,进行部分业务逻辑的处理,而在这个过程中,我们通常会使用session来保持用户的登陆状态。
然而,在微信小程序中,我们会遇到这样一个问题:使用原生小程序请求后端接口,无法在后端保持session,即同一个用户的不同请求之间无法共享session。
原因分析
对于微信小程序,玄妙的地方之一在于它只允许使用https协议通信,并且每次请求都需要在头部带上小程序的 session_key
。这导致了一个后端与小程序未经进行协商后就无法共享session的情况。
具体来说,无法共享session的原因在于:
- 微信小程序在请求时会带上
session_key
,但是同一个用户下的不同请求会产生不同的session_key
,使得后端无法根据session_key
确定当前请求的用户。 - 微信小程序只能使用 https 协议进行通信,而网站无法使用 https 协议,导致 https 和 http 的 session 无法共享。
综合上述原因,我们可以看到微信小程序无法使用原生的session进行用户认证和数据状态保持。
解决方案
解决微信小程序无法保持session的问题,目前有两种常见的实现方式。
使用HTTP协议头部信息
在小程序端使用原生的 wx.request()
访问后端接口时,可以携带 cookies
或者 Authorization
等验证信息,在后端解析相应的验证信息,根据验证信息设置对应的用户session状态。这样就可以实现用户状态保持了。
小程序端代码示例:
wx.request({
url: 'https://example.com/path/to/api',
header: {
'content-type': 'application/json', // 默认值
'cookie': 'PHPSESSID=abcdefg1234567; OtherCookie=foobar'
},
success: function(res) {
console.log(res.data)
}
})
在后端读取 cookie
不同语言实现会有所不同,比如在 Node.js 中,可以使用 cookie-parser
中间件,进行 cookie 解析:
const express = require('express');
const cookieParser = require('cookie-parser');
const app = express();
app.use(cookieParser());
app.get('/', function (req, res) {
// Read the user session data
const userSession = req.cookies.userSession;
...
});
使用Token身份验证
除了使用HTTP协议头部信息,也可以使用 Token 身份验证的方式来进行用户认证和状态保持。
Token 身份验证是一种基于 secret 的方案,使用 JSON Web Token (JWT) 就能在前后端实现状态保持。JWT 是一种开放标准(RFC 7519),用于在各方之间安全地将声明作为 JSON 对象传输,可以使用 HMAC 算法和 RSA 算法对 JWT 进行签名。
JSON Web Token 由三部分组成,分别是:
{
"alg": "HS256",
"typ": "JWT"
}
{
"sub": "123456",
"name": "John Doe",
"iat": 1516239022
}
"secret"
其中第一个部分是头部,描述 JWT 自身的信息。第二个部分是有效载荷(Payload),包含要传输的数据信息。第三个部分是签名(Signature),根据头部和有效载荷计算出来的。
在编写接口时,需要对用户进行身份验证,如果身份验证成功,则生成 JWT Token 返回给小程序端,小程序可以将该 Token 保存下来,再次访问后端时将 Token 作为请求参数传递给后端。后端接口需要对 header 或者 post body 中携带的 Token 进行验证,从而判断出当前请求对应的用户信息。
后端身份验证逻辑示例(Node.js):
const jwt = require('jsonwebtoken');
const privateKey = 'my-secret-key';
app.post('/api/login', function (req, res) {
const {username, password} = req.body;
// 验证用户身份,生成 token
const token = jwt.sign({username: username}, privateKey);
// 将 token 发送给小程序
res.send({token: token});
});
function verifyToken(req, res, next) {
const token = req.headers['x-token'];
jwt.verify(token, privateKey, function(err, decoded) {
if (err) {
// Token 验证失败
res.sendStatus(401);
} else {
// Token 验证成功,将 decoded 中的用户信息存到 req.user 中
req.username = decoded.username;
next();
}
});
}
app.post('/api/add', verifyToken, function (req, res) {
// 登录验证成功,在此处处理小程序的接口请求
...
});
在小程序端请求后端接口时,需要在请求 header 中携带 token 参数,示例如下:
wx.request({
url: 'https://example.com/path/to/api',
header: {
'content-type': 'application/json', // 默认值
'x-token': 'jwt-token-string'
},
success: function(res) {
console.log(res.data)
}
})
总结
本文讲解了微信小程序无法保持 session 的原因,以及如何使用 HTTP 协议头部信息和 Token 身份验证两种方式来实现用户认证和状态保持。其中,使用 Token 身份验证的方式可以克服 HTTP 协议头部信息无法跨协议传输的限制,具有更加灵活的应用场景,需要更多的用户自定义代码实现。
本文链接:https://my.lmcjl.com/post/11595.html
4 评论