跳转至

微信登录 SSO

微信登陆 SSO 是 NS WIKI 的一项登录服务,基于微信开放平台的网页扫码登录,对外提供标准的 OAuth2 授权码(Authorization Code)流程

在shipengliang大佬的帮助下注册得到的微信网页登陆能力。

用户用微信扫码授权后,第三方应用即可获取其微信昵称与头像,无需各自维护账号密码体系。

服务地址:https://nswiki.cn/wechat

这是什么

  • 用户:一个微信扫码登录入口。
  • 开发者:一个自建的 OAuth2 / OpenID Connect 风格的认证提供方(Identity Provider),应用通过标准流程换取用户身份信息。

支持的能力:

  • 微信扫码授权登录
  • 标准 OAuth2 授权码流程(authorization_code
  • refresh_token 刷新与轮换
  • OpenID Connect 风格的 UserInfo 端点
  • 「记住本设备」快速登录(60 天内免扫码)
  • 撤销授权(revoke)

接入流程概览

sequenceDiagram
    autonumber
    participant U as 用户
    participant App as 第三方应用
    participant SSO as NSWIKI SSO
    participant WX as 微信开放平台

    U->>App: 点击「微信登录」
    App->>SSO: 重定向到 /oauth/authorize
    SSO->>U: 展示微信扫码二维码
    U->>WX: 微信扫码并确认
    WX->>SSO: 回调 /oauth/callback(携带微信 code)
    SSO->>U: 展示授权确认页(是否授权给该应用)
    U->>SSO: 点击「同意」
    SSO->>App: 重定向回 redirect_uri(携带授权码 code)
    App->>SSO: POST /oauth/token(code + client_secret)
    SSO-->>App: 返回 access_token + refresh_token
    App->>SSO: GET /oauth/userinfo(Bearer access_token)
    SSO-->>App: 返回用户昵称、头像

快速开始

第 1 步:注册应用

联系 NS WIKI 管理员注册你的应用,获取 client_idclient_secret,并登记一个固定的 redirect_uri(回调地址)。

redirect_uri 必须完全一致

授权时传入的 redirect_uri 会与注册值做严格相等匹配,不一致将直接拒绝。 请连同协议(https://)、端口、路径一起登记准确。

第 2 步:引导用户到授权页

将用户浏览器重定向到:

https://nswiki.cn/wechat/oauth/authorize
  ?client_id=YOUR_CLIENT_ID
  &redirect_uri=https://example.com/callback
  &response_type=code
  &scope=profile
  &state=RANDOM_STATE
参数 必填 说明
client_id 注册应用时发放的 ID
redirect_uri 回调地址,须与注册值完全一致
response_type 固定为 code
scope 固定为 profile
state 防 CSRF 的随机串,会原样带回回调地址

务必校验 state

生成一个随机 state 并在回调时校验它是否一致,可防止跨站请求伪造(CSRF)攻击。

第 3 步:用授权码换 token

用户同意授权后,SSO 会重定向回你的 redirect_uri 并附带 codestate

https://example.com/callback?code=AUTHZ_CODE&state=RANDOM_STATE

应用后端用授权码换取 access_token

换取 access_token
curl -X POST https://nswiki.cn/wechat/oauth/token \
  -d "grant_type=authorization_code" \
  -d "code=AUTHZ_CODE" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  -d "redirect_uri=https://example.com/callback"

返回:

{
  "access_token": "9f3c...",
  "token_type": "Bearer",
  "expires_in": 7200,
  "refresh_token": "a71e...",
  "scope": "profile"
}

client_secret 只能放在后端

换 token 需要 client_secret绝不能出现在前端代码或浏览器中。 授权码有效期仅 10 分钟且只能使用一次。

第 4 步:获取用户信息

获取用户信息
curl https://nswiki.cn/wechat/oauth/userinfo \
  -H "Authorization: Bearer ACCESS_TOKEN"

返回(OpenID Connect UserInfo 风格):

{
  "sub": "oXXXX...",        // 用户唯一标识(openid)
  "nickname": "微信昵称",     // 微信昵称
  "picture": "https://..."   // 头像 URL
}

API 端点

方法 端点 说明
GET /wechat/ 服务主页与 API 简介
GET /wechat/oauth/authorize 授权入口(扫码登录页)
POST /wechat/oauth/token 授权码换 token / 刷新 token
GET /wechat/oauth/userinfo 获取当前授权用户信息
POST /wechat/oauth/revoke 撤销 access_token 或 refresh_token
GET /wechat/logout 退出登录(清除快速登录凭证)

刷新 token

access_token 有效期 2 小时。过期后用 refresh_token 续期:

刷新 token
curl -X POST https://nswiki.cn/wechat/oauth/token \
  -d "grant_type=refresh_token" \
  -d "refresh_token=REFRESH_TOKEN" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET"

refresh_token 会轮换

每次刷新都会签发新的 refresh_token 并使旧的立即失效。 请保存每次返回的最新 refresh_token,旧的不要再用。

撤销授权

撤销 token
curl -X POST https://nswiki.cn/wechat/oauth/revoke \
  -d "token=ACCESS_OR_REFRESH_TOKEN" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET"

有效期一览

凭证 默认有效期
授权码 code 10 分钟(一次性)
access_token 2 小时
refresh_token 30 天(每次刷新轮换)
快速登录凭证 60 天

错误码

error 出现位置 说明
invalid_client token / revoke client_idclient_secret 错误
invalid_grant token 授权码或 refresh_token 无效 / 已过期 / 已使用
unsupported_grant_type token grant_type 不是 authorization_coderefresh_token
invalid_request userinfo 缺少 Authorization: Bearer
invalid_token userinfo access_token 无效或已过期
access_denied 授权回调 用户在确认页点击了「拒绝」

快速登录(记住本设备)

用户在授权确认页勾选「记住本设备」后,SSO 会种下有效期 60 天的快速登录凭证。 此后同一设备再次进入授权页时,可一键登录、无需再次扫码,直到凭证过期或用户主动退出 / 清除。

安全说明

  • 所有令牌在数据库中只存 SHA-256 哈希,不存明文。
  • 授权回调使用 state 做 CSRF 校验。
  • 授权确认通过短期签名凭证完成,避免微信跳转导致会话丢失。
  • redirect_uri 严格匹配,防止授权码被劫持到恶意地址。