认证机制

Passport 采用无状态 JWT 作为认证凭据。服务端不保存会话(Session),所有身份信息都封装在 Token 中,由持有公钥的一方在本地完成校验。

早期版本中基于服务端会话(sessionId + passport_session Cookie)的认证方式已在 Go 版本中移除,当前不存在任何 Session 相关接口。

Token 概述

项目说明
类型JWT(JSON Web Token)
签名算法ES256(ECDSA + SHA-256),服务端硬编码,不可配置
有效期签发后 24 小时,固定值,不支持续期
传递方式Cookie passport_token,或请求头 passport-token

Claims 结构

Claim说明
acid账号 ID(雪花 ID)
uid用户 ID,即登录名
tid租户 ID
pids权限 ID 数组
iat签发时间戳,用于账号级吊销比对
jtiToken 唯一标识
exp过期时间戳

Token 过期后需重新登录(个人账号)或重新申请(应用账号)。

账号停用与 Token 立即失效

账号被停用(HR 离职同步或管理员手动停用)时,Passport 记录吊销时刻:签发于该时刻之前的 Token 即使未过期,也会在校验时被直接拒绝。详见企业身份与 HR 联动。

认证方式一:用户名 / 密码登录

适用于真人用户通过页面或客户端登录的场景。

流程

1. 登录             POST /api/passport/service/v1/login          →  token
2. 上次登录失败时,先补验证码再重登:
   2.1 获取滑块验证码   GET  /api/passport/service/v1/verify/image
   2.2 校验滑块验证码   POST /api/passport/service/v1/verify/image   →  captchaToken
   2.3 携带 captchaToken 重新登录

首次登录(或上次登录成功)无需图片验证码,直接提交登录名与密码即可。

账密输错一次后,该账号的下一次登录必须携带滑块验证码:先调用「生成滑块验证码」获取底图、拼图块与缺口位置,采集用户拖动滑块的落点坐标(point 为 "x,y",容差 4 像素)提交换取 captchaToken,再重新登录。未携带时返回 10007 Captcha verification required after a failed attempt;携带但校验未通过返回 10005 Captcha verification failed,均不会校验密码。

登录成功后失败计数清零,后续登录恢复免验证码。

登录成功

  • 响应体中返回 token 与 username
  • 同时下发两个 Cookie:passport_token(Token)与 passport_username(用户名或登录名),有效期由服务端配置决定(默认 86400 秒)

登录失败

登录失败不返回 HTTP 错误码,而是返回 HTTP 200 并在 body 中携带业务错误码,接入方必须解析 code 判断:

业务码说明
10001账号不存在
10002密码错误
10003连续失败次数超限,账号已锁定
10004账号已禁用
10005滑块验证码校验失败
10006企业账号待激活,需先完成激活(见企业身份与 HR 联动)

连续失败超过服务端配置的阈值(默认 5 次)后账号被锁定;登录成功后失败计数清零。密码以 BCrypt 存储与比对。

登出

调用 DELETE /api/passport/service/v1/login 清除客户端 Cookie。由于服务端无状态,登出不会使 Token 立即失效,已签发的 Token 在过期前仍可通过校验。

认证方式二:AK / SK 换取 Token

适用于服务间调用(应用账号)的场景,无需人工登录。

流程

1. 生成签名   POST /api/passport/service/v1/token/signature  →  signature + timestamp
2. 换取 Token POST /api/passport/service/v1/token            →  token

第一步:提交 accessKeyId 与 secretAccessKey,服务端返回签名与毫秒时间戳。签名算法为:

signature = UPPER(HEX(HMAC-SHA256(secretAccessKey, accessKeyId + timestamp)))

第二步:提交 accessKeyId、timestamp、signature 换取 Token。服务端会重新计算签名比对,并校验应用账号凭证是否存在。

使用 SDK 时,上述两步与 Token 缓存均由 SDK 内部完成,无需手动调用。Go SDK 的 Token 缓存周期为 3600 秒。

服务端如何校验请求

passport-service 按下述顺序处理每一个请求:

  1. 请求路径命中配置的鉴权路径模式时进入校验,否则直接放行
  2. 注册接口(POST /account)与找回密码接口(/account/forgot-password/*)显式豁免
  3. 优先从 Cookie passport_token 读取 Token,为空时读取请求头 passport-token
  4. 校验签名与有效期
  5. 校验通过则将 acid / uid / tid / pids 写入请求上下文供后续处理使用;校验失败返回 HTTP 401 与 {"code":11002,"message":"Not authorized"}

业务服务接入时无需自行实现上述逻辑,直接使用 SDK 提供的中间件即可,参见「SDK 集成(Java)」与「SDK 集成(Go)」。

修改密码

当前版本不提供已登录状态下的修改密码接口。修改密码请通过「找回密码」流程完成:滑块验证码 → 邮箱验证码 → 重置密码。详见「公开接口」的 Forgot Password 模块。

接入方注意:调用 PUT /api/passport/service/v1/account 更新账号时,请求体中不要携带 password 字段。该接口为全量保存,明文密码会覆盖数据库中的 BCrypt 密文,导致账号永久无法登录。