跳到主要内容

OAuth2 应用接入

OAuth2 用于让外部应用在获得授权后调用卷王接口。例如,企业培训门户需要读取当前登录用户的基本信息,可以配置一个独立客户端,并申请 user.read 范围。

这里的卷王是授权服务端。若希望用户通过钉钉、企业微信等账号登录卷王,请查看对应的第三方集成;若业务系统需要签发问卷免登录链接,请查看 JWT 认证。三者的配置用途不同。

配置入口​

管理员进入 管理后台 → 系统管理 → OAuth 2.0,在应用管理列表点击 新建。

当前 Chrome 中新增 OAuth2 客户端的基础字段

本文使用“培训门户(文档演示)”展示字段填写,客户端密钥留空,表单未保存。example.com 地址仅为示例,不是可直接使用的接入服务。

填写客户端信息​

字段填写说明
客户端编号外部应用使用的 client_id,例如 training-portal-demo;为不同应用分别配置
客户端密钥由接入双方妥善保管,供服务端换取令牌使用;不要放入网页源码、截图或公共仓库
应用名、图标、描述用于识别应用,建议写清所属业务和用途
状态配置完成并准备接入时再开启
访问令牌的有效期单位是秒;表单默认 1800,即 30 分钟
刷新令牌的有效期单位是秒;表单默认 43200,即 12 小时
授权类型仅选择接入方实际使用的类型;授权码流程选 authorization_code,需要刷新时同时配置 refresh_token
授权范围允许申请的 scope,例如读取用户信息所需的 user.read
自动授权范围可自动通过的范围;初次接入可留空,由用户确认授权
可重定向的 URI 地址应用接收授权结果的完整地址,例如 https://portal.example.com/oauth/callback;协议、主机、端口和路径都应与应用配置一致

授权码类型、user.read 授权范围与回调地址的填写示例

授权范围和回调地址使用可输入的多选框,输入一项后按回车确认。配置完成后点击 确定,再由接入方进行联调。

不要直接复用系统现有客户端的编号、密钥或默认权限。某个 scope 是否真正限制了业务接口,取决于该接口的权限校验;新增一个 scope 名称不会自动把所有接口限制在该范围内。

授权码接入过程​

当前管理后台提供客户端和令牌管理。授权信息、授权确认和换取令牌由后端接口提供;创建客户端不会自动生成一个可嵌入的登录或授权页面。接入方需要对接登录状态、授权确认页面和回调处理。

  1. 用户登录卷王,授权页面获取客户端名称与可申请范围。
  2. 授权页面让用户确认范围,例如允许读取基本信息。
  3. 前端提交授权决定,收到回调 URL 后跳转到外部应用。
  4. 外部应用校验 state,取得授权码,由自己的服务端使用客户端凭证换取访问令牌。
  5. 服务端带上 Authorization: Bearer <access_token> 调用获准接口。
  6. 令牌过期后,按已启用的授权类型刷新;用户撤销授权或业务停用时撤销令牌。

当前接口约定​

下面使用默认后端前缀 /admin-api。实际部署若经过网关,应以部署后的 API 地址为准,不能把前端页面地址直接当成接口地址。

接口用途与认证
GET /admin-api/system/oauth2/authorize?clientId=…获取授权信息;需要用户已登录,返回 JSON
POST /admin-api/system/oauth2/authorize提交授权决定;需要用户已登录,返回的 data 是回调 URL,由前端处理跳转
POST /admin-api/system/oauth2/token换取或刷新令牌;使用 HTTP Basic 传递客户端编号和密钥
POST /admin-api/system/oauth2/check-token校验令牌;使用 HTTP Basic 客户端认证,并传入 token
DELETE /admin-api/system/oauth2/token撤销令牌;使用 HTTP Basic 客户端认证,并传入 token
GET /admin-api/system/oauth2/user/get读取当前用户基本信息;需要访问令牌和 user.read 范围

授权确认接口使用表单参数:response_type=code、client_id、redirect_uri、state、auto_approve、scope。其中 scope 是 JSON 字符串,例如 {"user.read":true};手动确认使用 auto_approve=false。自动授权未通过时可能返回空 URL,接入页面应继续让用户确认,不能直接当成成功。

换取令牌的 scope 参数则采用空格分隔的范围列表,两处格式不同。

换取令牌示例​

以下代码只说明请求格式,所有大写值都需要替换;应在外部应用的服务端执行。

curl --request POST 'https://survey.example.com/admin-api/system/oauth2/token' \
--user 'CLIENT_ID:CLIENT_SECRET' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'code=AUTHORIZATION_CODE' \
--data-urlencode 'redirect_uri=https://portal.example.com/oauth/callback' \
--data-urlencode 'state=STATE_FROM_AUTHORIZATION'

当前接口把结果放在统一响应的 data 中。判断成功时同时检查业务响应码和返回的令牌字段,不要只检查 HTTP 200。刷新请求将 grant_type 改为 refresh_token,并传入 refresh_token;客户端也需允许该授权类型。

调用用户信息接口时使用换取的访问令牌:

GET /admin-api/system/oauth2/user/get
Authorization: Bearer ACCESS_TOKEN

管理令牌​

进入 系统管理 → OAuth 2.0 → 令牌管理,按用户编号、用户类型等条件查询,查看令牌详情和过期时间。需要结束一条现有会话时,使用该记录的 强退 操作,并按页面提示确认。

令牌列表包含访问令牌和刷新令牌,截图或提交工单时不要直接公开完整值。关闭客户端、令牌自然过期和强退现有令牌是不同操作;停用接入时应核对现存令牌及应用端缓存。

常见问题​

现象检查方法
新建后没有出现“第三方登录”按钮OAuth2 客户端管理用于外部应用接入;登录按钮由对应登录集成配置决定
换取令牌失败核对客户端状态、HTTP Basic 凭证、授权类型、授权码是否有效,以及回调地址与 state 是否一致
读取用户信息被拒绝检查令牌是否过期,以及是否获准 user.read;仅填写客户端范围不代表本次令牌已经获得该范围
授权接口只返回 JSON这是当前前后端分离接口约定;授权页面负责展示确认及处理回调 URL
选择了 implicit 却无法调用 token 接口当前 token 接口不接受 implicit;使用与接入流程匹配的授权码等类型
配置了 scope,但业务接口仍可访问核对该业务接口的权限实现,不能把客户端范围配置当成所有接口的自动隔离机制

上线前应由接入方确认用户确认流程、回调校验、令牌保管及退出行为,并用独立测试客户端完成联调。