# Oauth2接入
# 5.1 Code模式接入
# 5.1.1 请求code
请求头:header
Authorization: 值在页面登陆后,任意查看一个接口复制
http(s):{host}:{port}/api/auth/oauth/authorize?responseType=code&clientId=81699abe-c975-4a8d-bf6f-0a015568422e&redirectUri=http://192.168.97.163:8082/callback&scope=all
参数名 | 描述 | 类型 | 为空 | 备注 |
---|---|---|---|---|
responseType | 填写code | String | 必填 | |
clientId | 开发者使用api唯一标识 | String | 必填 | 认证系统分配 |
redirectUri | 回调地址 | String | 必填 | |
scope | 默认all | String | ||
state | 状态state | String |
如果没有登录,会自动跳转到统一认证登录页面,登录后,redirect_uri
填写的回调地址会收到来自于统一认证的GET
请求,并附带如下参数:
redirect_uri?code=<CODE>&state=<STATE>
例如:
http://192.168.97.163:8082/callback?code=0a015568422e&state=111
参数 | 说明 |
---|---|
code | 由认证服务器生成 |
state | 第三方系统自己维护状态码 |
# 5.1.2 根据code获取access Token(HTTP POST)
接入的Web应用应在获取到code之后,向如下地址发送POST
请求: https://{host}:{port}/api/auth/oauth/token
Json body:
{
"clientId": "81699abe-c975-4a8d-bf6f-0a015568422e",
"clientSecret": "d440049d-1b1a-49ba-8f56-0920bc83b9b2",
"code": "F19353585910571175D17A0F9B2ACA28"
}
参数名 | 描述 | 类型 | 为空 | 备注 |
---|---|---|---|---|
code | 填写code | String | 必填 | 由第一步回调地址参数获得 |
clientId | 开发者使用api唯一标识 | String | 必填 | 认证系统分配 |
clientSecret | 与clientId对应的秘钥 | String | 必填 | 认证系统分配 |
返回结果:
{
"code": 0,
"data": {
"accessToken": "f33fbb0be5c94d51b2ea3e23ad214175",
"expiredIn": 3600,
"scope": "all",
"refreshToken": "0a775950fd9f463093bdcc2fa8e4cf76",
"tokenType": "header"
}
}
错误返回:
{
"msg": "无效的code:e09715810ae641a6bb086d72a91b344!",
"code": 10001
}
常见错误码 | 描述 |
---|---|
10001 | 无效的code:%s! |
10002 | 无效的client id:%s! |
10003 | 回调链接(redirectUri)无效:%s! |
10004 | Client Secret:%s 校验失败! |
10005 | 无效的Access Token: %s! |
# 5.1.3 获取用户信息(HTTP GET)
接口地址:
http(s)://{host}:{port}/api/auth/profile
请求头:
参数名 | 描述 | 类型 | 为空 |
---|---|---|---|
3rd-party-ac-token | 第二步获取的token | String | 必填 |
返回值
参数名 | 描述 |
---|---|
code | 返回标识(0.正常 500.错误) |
msg | 操作信息 |
data.userId | 用户id |
data.sex | 用户性别 |
data.avatar | 头像地址 |
data.username | 用户工号 |
data.nick | 用户姓名 |
data.status | 账号状态(0.启用 1.禁用) |
data.phonenumber | 手机号 |
data.email | 邮箱 |
data.role.id | 角色id |
data.role.name | 角色名称 |
data.role.code | 角色代码(xs:学生,js:教师,子应用管理员:sub_application_manager,院系(单位)管理员:college_manage,游客:sys:visitor,开发商:sys:kfs) |
data.role.deptId | 部门id |
data.role.deptCode | 部门代码 |
data.role.deptName | 部门名称 |
返回示例
{
"code": 0,
"msg": "请求成功",
"data": {
"userId": 47261,
"sex": "男",
"avatar": "",
"username": "jc_data",
"nick": "集成-数据中台",
"status": "0",
"phonenumber": "13888888888",
"email": "xxxx@qq.com",
"role": {
"id": 1,
"name": "学生",
"code": "xs",
"deptId": 1054,
"deptCode": "0",
"deptName": "半云学院"
}
}
}
错误示例:
{
"msg": "无效的Access Token: 218204ed282249f6baead992a5297db!",
"code": 10005
}
# 5.1.4 退出登陆 (HTTP GET)
调用地址:
http(s)://{ip}:{port}/api/auth/user/logout
请求头:
3rd-party-ac-token: 由cas/oauth2接口获取用户access-token
返回值
参数名 | 描述 |
---|---|
code | 返回标识(0.正常) |
msg | 操作信息 |
data | 返回信息 |
返回示例
{
"code": 0,
"msg": "请求成功",
"data": null
}
# 5.1.5 Token校验 (HTTP POST)
调用地址:
http(s)://{ip}:{port}/api/auth/valid/token
请求体(form data)
参数名 | 描述 | 类型 | 为空 | 备注 |
---|---|---|---|---|
accessToken | 登陆凭证 | String | 必填 | 由cas/oauth2接口获取用户access-token |
返回值
参数名 | 描述 |
---|---|
code | 返回标识(0.正常) |
msg | 操作信息 |
data | 返回信息 |
返回正确示例
{
"code": 0,
"msg": "请求成功",
"data": null
}
返回错误示例
{
"msg": "无效的Access Token: 0d0418da545746639c63da18df56d8f21!",
"code": 10005
}
# 5.2 Java回调方法示例
@RestController
public class OAuth2Callback {
private final AuthConfig authConfig;
private final AuthClient authClient;
public OAuth2Callback(AuthConfig authConfig, AuthClient authClient) {
this.authConfig = authConfig;
this.authClient = authClient;
}
/**
* 处理oauth2 code
*
* @param code 由认证服务器转发 code
* @return Resp<?>
*/
@GetMapping("/oauth2/callback")
public Resp<?> codeCallback(@RequestParam("code") String code) {
AuthClientConfig oAuth2Config = authConfig.getOauth2();
// step 1. 使用 code 换取用户access token
Code2TokenReq req = new Code2TokenReq();
req.setCode(code);
req.setClientId(oAuth2Config.getClientId());
req.setClientSecret(oAuth2Config.getClientSecret());
Resp<AccessTokenInfo> accessTokenInfoResp = authClient.oauth2CodeToAccessToken(req);
// step 2. 使用 access token 获取用户信息
if (RespUtil.success(accessTokenInfoResp)) {
AccessTokenInfo accessTokenInfo = accessTokenInfoResp.getData();
String accessToken = accessTokenInfo.getAccessToken();
CurrentRequest.setAccessToken(accessToken);
// step 3. 跳转到自己的系统(请自行处理)
return authClient.profile();
}
return accessTokenInfoResp;
}
}
# 5.3 客户端密码模式
# 5.3.1 根据客户端密码获取access Token(HTTP POST)
http(s):{host}:{port}/api/auth/oauth/password/token
参数名 | 描述 | 类型 | 为空 | 备注 |
---|---|---|---|---|
clientId | 开发者使用api唯一标识 | String | 必填 | 认证系统分配 |
clientSecret | 客户端访问密钥 | String | 必填 | |
username | 用户账号 | String | 必填 | |
password | 用户密码 | String | 必填 |
返回结果:
{
"code": 0,
"msg": "请求成功",
"data": {
"accessToken": "2c1abe81933f48b8929c83f7e3dd2f66",
"expiredIn": 3600,
"scope": "all",
"refreshToken": "20a80eb27500499fbe830a6c34a59b5c",
"tokenType": "header"
}
}
错误返回:
{
"code": 10000,
"msg": "授权失败:账号或密码错误! 账号剩余4次尝试机会!",
}
常见错误码 | 描述 |
---|---|
10000 | 授权失败:账号或密码错误! 账号剩余%s次尝试机会! |
10002 | 无效的client id:%s! |
10004 | Client Secret:%s 校验失败! |
10007 | 当前client id: %s,不支持 grant type: password |
# 5.3.2 Token使用
根据5.1.3 获取用户信息 、5.1.4 退出登陆、5.1.5 Token校验使用Token
← 四、CAS标准版接入 六、CAS接口版接入 →