登录鉴权是小程序接入业务系统时首先要解决的问题。小程序不能像传统 Web 应用那样让用户输入账号密码,而是通过平台提供的登录能力完成身份识别。理解 code2session 与 token 的完整链路,是做好小程序后端的关键。

一、登录流程全景

小程序登录分为静默登录和授权登录两级,核心流程如下:

  1. 小程序端调用 wx.login() 获取临时凭证 code
  2. 小程序端将 code 发送给后端服务器
  3. 后端携带 code + app_id + app_secret 调用平台 code2session 接口
  4. 平台返回 openid(用户唯一标识)和 session_key(会话密钥)
  5. 后端用 openid 关联业务用户,签发自己的 token 返回给小程序端
  6. 后续请求携带 token,后端校验即可

二、静默登录(code2session)

// 小程序端
wx.login({
  success(res) {
    if (res.code) {
      request('/api/auth/login', { code: res.code });
    }
  },
});
// 后端 Node.js 示例
const http = require('https');

async function code2session(code) {
  const url = 'https://api.example.com/sns/jscode2session'
    + '?appid=' + APP_ID
    + '&secret=' + APP_SECRET
    + '&js_code=' + code
    + '&grant_type=authorization_code';

  return new Promise((resolve, reject) => {
    http.get(url, res => {
      let data = '';
      res.on('data', d => data += d);
      res.on('end', () => resolve(JSON.parse(data)));
    }).on('error', reject);
  });
}

返回结果中最重要的两个字段:

  • openid:用户在当前小程序下的唯一标识,跨平台时注意区分 unionid
  • session_key:会话密钥,用于解密敏感数据或校验签名,不可下发到前端
注意:session_key 必须保存在服务端,绝不能返回给小程序端。若泄露到客户端,攻击者可解密用户敏感信息。

三、授权登录(获取用户信息)

新版小程序规范中,获取用户昵称头像需要用户主动点击授权按钮,接口返回加密数据,需要服务端用 session_key 解密:

// 服务端用 session_key 解密用户信息
function decrypt(encryptedData, iv, sessionKey) {
  const crypto = require('crypto');
  const decipher = crypto.createDecipheriv(
    'aes-128-cbc',
    Buffer.from(sessionKey, 'base64'),
    Buffer.from(iv, 'base64')
  );
  let decoded = decipher.update(encryptedData, 'base64', 'utf8');
  decoded += decipher.final('utf8');
  return JSON.parse(decoded);
}

解密后能拿到 openidunionidnickNameavatarUrl 等信息,校验 watermark 中的 appid 防止伪造。

四、服务端 token 设计

平台返回的 openid 只是"识别用户",业务侧通常签发自己的会话 token:

const jwt = require('jsonwebtoken');

// 登录成功后签发 token
function issueToken(userId, sessionKey) {
  return jwt.sign(
    { sub: userId, type: 'mini_user' },
    SECRET,
    { expiresIn: '7d' }
  );
}
  • token 有效期建议 7 天左右,配合"静默续期"机制
  • token 中不要放敏感信息,只放身份标识
  • 退出登录 / 换绑等场景需要失效 token,可在服务端维护黑名单或版本号

五、静默登录的常见坑

  • code 一次性且短期有效:每次登录都重新调用 wx.login(),不要缓存 code
  • session_key 过期:解密失败时引导用户重新登录
  • appid 不符:解密后的 watermark 中 appid 与自己的不一致,说明数据非法
  • 接口校验:后端必须校验 code 来源,防止批量刷 token

六、业务安全补充

登录只是鉴权的第一步,业务接口还需要:

  • 接口层统一校验 token,按用户维度做权限控制
  • 对高频敏感接口做频率限制,防止恶意调用
  • 金额、权益类操作做好幂等与流水记录

小结

小程序的登录本质是"平台帮你完成身份确认,业务方自己维护会话"。把 code2session、session_key 的保密、业务 token 签发这几个环节做对,登录鉴权就稳了。这也是后面对接支付、提现等功能的基础。