芋道开源项目开放平台接入指南
🔧 核心实现说明
修改的关键文件
1. OAuth2GrantServiceImpl.java
文件路径: yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2GrantServiceImpl.java
实现的核心方法: grantClientCredentials
@Override
public OAuth2AccessTokenDO grantClientCredentials(String clientId, List<String> scopes) {
// 1. 获取客户端信息
OAuth2ClientDO client = oauth2ClientService.validOAuthClientFromCache(clientId);
// 2. 处理scope逻辑
List<String> finalScopes = determineFinalScopes(client, scopes);
// 3. 创建令牌(使用虚拟用户ID,仅用于标识客户端令牌)
Long virtualUserId = -1L; // 使用负数表示这是客户端令牌,不是真实用户
return oauth2TokenService.createAccessToken(virtualUserId, UserTypeEnum.ADMIN.getValue(),
clientId, finalScopes);
}
private List<String> determineFinalScopes(OAuth2ClientDO client, List<String> requestedScopes) {
List<String> clientScopes = client.getScopes();
// 如果没有请求特定scope,使用客户端配置的所有scope
if (CollUtil.isEmpty(requestedScopes)) {
log.info("[grantClientCredentials] 未指定scope,使用客户端配置的所有权限: {}", clientScopes);
return clientScopes;
}
// 如果请求了特定scope,验证是否在允许范围内
for (String requestedScope : requestedScopes) {
if (!clientScopes.contains(requestedScope)) {
throw exception(OAUTH2_CLIENT_SCOPE_OVER);
}
}
log.info("[grantClientCredentials] 使用请求的scope: {}", requestedScopes);
return requestedScopes;
}
实现特点:
- ✅ 支持OAuth2 client_credentials模式
- ✅ 支持可选scope参数(不传时使用客户端配置的所有权限)
- ✅ 传scope时验证是否在客户端允许范围内
- ✅ 使用虚拟用户ID(-1)避免用户绑定复杂性
- ✅ 完整的日志记录和错误处理
2. OAuth2TokenServiceImpl.java
修改内容: 在buildUserInfo
方法中添加对虚拟用户ID的处理
private Map<String, String> buildUserInfo(Long userId, Integer userType) {
// 处理客户端模式(client_credentials)的情况
if (userId == -1L) {
return MapUtil.builder(LoginUser.INFO_KEY_NICKNAME, "开放API客户端")
.put(LoginUser.INFO_KEY_DEPT_ID, null).build();
}
// 其他用户类型的处理逻辑...
}
📖 项目简介
本文档基于芋道开源项目(yudao-cloud),为第三方开发者提供完整的开放平台API接入指南。芋道开源项目是一套全部开源的企业级快速开发平台,采用现代化的架构设计,支持多租户、微服务等特性。
🚀 开放平台特性
核心特性
- 标准OAuth2认证:基于OAuth2 client_credentials模式
- 灵活权限控制:通过scope配置精确控制API访问权限
- 简化接入流程:支持可选scope参数,降低接入门槛
- 安全可靠:访问令牌短期有效,支持自动刷新机制
- 完整监控:提供访问日志、错误统计等监控能力
技术架构
- 认证方式:OAuth2 client_credentials
- 权限模型:基于scope的资源访问控制
- 令牌格式:JWT或UUID格式访问令牌
- 传输协议:HTTPS加密传输
- 数据格式:JSON格式请求和响应
🔧 快速开始
1. 获取客户端凭证
联系管理员获取以下信息:
client_id
:客户端标识符client_secret
:客户端密钥scopes
:授权范围(如:device:read, device:write, data:read, data:write)
2. 获取访问令牌
方式一:使用所有配置权限(推荐新手)
curl -X POST "https://your-domain.com/admin-api/system/oauth2/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Authorization: Basic $(echo -n 'client_id:client_secret' | base64)" \
-d "grant_type=client_credentials"
方式二:指定特定权限范围(推荐生产环境)
curl -X POST "https://your-domain.com/admin-api/system/oauth2/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Authorization: Basic $(echo -n 'client_id:client_secret' | base64)" \
-d "grant_type=client_credentials&scope=device:read,data:read"
响应示例
{
"code": 0,
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 7200,
"scope": "device:read device:write"
},
"msg": "操作成功"
}
3. 调用开放API
使用获取到的访问令牌调用API:
curl -X GET "https://your-domain.com/admin-api/open-api/device/info?deviceId=123" \
-H "Authorization: Bearer {access_token}"
📋 API接口文档
设备管理API
获取设备信息
- 接口地址:
GET /admin-api/open-api/device/info
- 所需权限:
device:read
- 请求参数:
deviceId
(必填):设备ID
请求示例:
curl -X GET "https://api.example.com/admin-api/open-api/device/info?deviceId=123" \
-H "Authorization: Bearer {access_token}"
响应示例:
{
"code": 0,
"data": {
"deviceId": "123",
"deviceName": "温度传感器-001",
"deviceType": "温度传感器",
"status": "在线",
"lastUpdateTime": "2024-01-15T10:30:00"
},
"msg": "操作成功"
}
获取设备列表
- 接口地址:
GET /admin-api/open-api/device/list
- 所需权限:
device:read
- 请求参数:
pageNo
(可选):页码,默认1pageSize
(可选):每页大小,默认10
上报设备数据
- 接口地址:
POST /admin-api/open-api/device/data
- 所需权限:
device:write
- 请求体:JSON格式设备数据
请求示例:
curl -X POST "https://api.example.com/admin-api/open-api/device/data" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json" \
-d '{
"deviceId": "123",
"temperature": 25.5,
"humidity": 60.2,
"timestamp": "2024-01-15T10:30:00"
}'
更新设备状态
- 接口地址:
PUT /admin-api/open-api/device/status
- 所需权限:
device:write
- 请求体:包含deviceId和status的JSON对象
🔐 权限范围说明
可用的Scope权限
Scope | 说明 | 适用接口 |
---|---|---|
device:read | 设备读取权限 | 设备信息查询、设备列表获取 |
device:write | 设备写入权限 | 设备数据上报、设备状态更新 |
data:read | 数据读取权限 | 历史数据查询、统计数据获取 |
data:write | 数据写入权限 | 数据上报、数据导入 |
权限组合建议
只读监控应用:
scopes: ["device:read", "data:read"]
设备管理应用:
scopes: ["device:read", "device:write"]
数据采集应用:
scopes: ["device:write", "data:write"]
全功能应用:
scopes: ["device:read", "device:write", "data:read", "data:write"]
⚠️ 错误码说明
认证相关错误
错误码 | 说明 | 解决方案 |
---|---|---|
40001 | 无效的客户端 | 检查client_id和client_secret |
40002 | 无效的访问令牌 | 重新获取访问令牌 |
40003 | 访问令牌已过期 | 使用刷新令牌或重新获取 |
权限相关错误
错误码 | 说明 | 解决方案 |
---|---|---|
40301 | 授权范围不足 | 联系管理员扩大scope权限 |
1002020001 | scope超出范围 | 检查请求的scope是否在配置范围内 |
业务相关错误
错误码 | 说明 | 解决方案 |
---|---|---|
400 | 请求参数错误 | 检查请求参数格式和必填项 |
404 | 资源不存在 | 检查请求的资源ID是否正确 |
500 | 服务器内部错误 | 联系技术支持 |
🛡️ 安全最佳实践
1. 令牌管理
- 访问令牌有效期为2小时,建议在过期前30分钟刷新
- 不要在客户端代码中硬编码client_secret
- 定期轮换客户端密钥
2. 网络安全
- 必须使用HTTPS传输
- 实施IP白名单限制(如需要)
- 监控异常访问模式
3. 错误处理
- 实现指数退避重试机制
- 正确处理令牌过期情况
- 记录详细的错误日志
📊 监控和限流
调用限制
- 每个客户端每分钟最多1000次API调用
- 单个IP每分钟最多500次认证请求
- 超出限制将返回429错误码
监控指标
- API调用成功率
- 平均响应时间
- 错误率统计
- 令牌使用情况
📝 更新日志
v1.0.0 (2024-01-15)
- 初始版本发布
- 支持OAuth2 client_credentials模式
- 提供设备管理相关API
- 实现基于scope的权限控制
芋道开源项目 - 让每个人都能快速搭建企业级应用!
项目地址:https://gitee.com/zhijiantianya/ruoyi-vue-pro