小程序登录鉴权实战:wx.login 换码与登录态校验

11 ℃ 0 条
内容摘要小程序登录鉴权没有 Cookie 会话可用。本文从 wx.login 取临时 code 讲到服务端 code2session 换 openid,再签发自定义 token 存入 Redis、编写接口鉴权中间件,并给出 session_key 不下发前端等安全要点。
小程序登录鉴权实战:wx.login 换码与登录态校验

小程序登录鉴权没有 Cookie 会话可用。用户进页面后先调 wx.login 拿临时 code,再由服务端换取 openid 与 session_key,最后签发出本站登录凭证。任一环写错都会导致「登录成功却接口 401」。

一、登录链路与 code 换取会话

wx.login 只取一张一次性票据 code,身份校验在服务端与微信之间完成,code 必须交给后端处理。

1. wx.login 拿到临时 code

code 五分钟有效且只能用一次,前端应立刻发给登录接口,不要缓存。回调里没有 openid。

// 前端:登录换取本站凭证
wx.login({ success: ({ code }) => wx.request({
  url: "https://api.example.com/auth/login", data: { code },
  success: (res) => wx.setStorageSync("token", res.data.token),
})});

2. 后端 code2session 换取 openid

服务端带 appid、secret 调用 code2session,成功返回 openid 与 unionid,openid 是本小程序的用户标识。

// 后端:用 code 换取身份
const r = await axios.get("https://api.weixin.qq.com/sns/jscode2session",
  { params: { appid, secret, js_code: code, grant_type: "authorization_code" } });
const { openid } = r.data;   // session_key 只留服务端

二、登录态签发与接口鉴权

微信不提供长期凭证,wx.checkSession 只能判断 session_key 是否有效,业务需自签登录态。

1. 自定义 token 的签发与鉴权

服务端生成随机 token,把 token 与 openid 的映射写进 Redis 并设过期时间。需登录的接口都挂 auth 中间件校验。

// 后端:签发 7 天登录态 + 鉴权中间件
const token = crypto.randomBytes(24).toString("hex");
await redis.set(`sess:${token}`, openid, "EX", 604800);

async function auth(req, res, next) {
  const t = (req.headers.authorization || "").slice(7);
  const uid = t && await redis.get(`sess:${t}`);
  if (!uid) return res.status(401).json({ code: 401 });
  req.user = { openid: uid };          // 滑动续期
  next();
}

前端把 token 存进 wx.setStorageSync,每个请求在头里带上;遇到 401 应清理并重新登录。

三、常见问题与安全要点

1. session_key 不得下发到前端

session_key 是解密用户数据的密钥,下发到前端等于公开,解密都应在服务端完成,secret 更不能写进小程序代码。

2. 登录态过期与并发处理

多端登录会产生多个 token;若要单端在线,需维护 openid 到 token 的索引,过期后前端可静默重登。

关键配置提示

  • code 五分钟有效且一次性,必须即时交换,不要缓存。
  • session_key 与 secret 只留服务端,前端只持有自定义 token。
  • token 存 Redis 设过期时间,接口统一走鉴权中间件。

发表评论 (已有0条评论)

快来评论,快来抢沙发吧~