diff --git a/doc/WPS365集成使用说明.md b/doc/WPS365集成使用说明.md index 9a8a11c..0f1a99a 100644 --- a/doc/WPS365集成使用说明.md +++ b/doc/WPS365集成使用说明.md @@ -32,7 +32,8 @@ wps365: # 应用密钥(从WPS365开放平台获取) app-key: YOUR_APP_KEY # 授权回调地址(需要在WPS365开放平台配置) - redirect-uri: https://your-domain.com/jarvis/wps365/oauth/callback + # 注意:使用 /wps365-callback 路径,避免前端路由拦截 + redirect-uri: https://your-domain.com/wps365-callback # API基础地址(一般不需要修改) api-base-url: https://open.wps.cn/api/v1 # OAuth授权地址(一般不需要修改) @@ -43,6 +44,11 @@ wps365: refresh-token-url: https://open.wps.cn/oauth2/v1/token ``` +**重要提示**: +- 回调地址使用 `/wps365-callback` 而不是 `/jarvis/wps365/oauth/callback` +- 这样可以避免前端路由拦截,确保OAuth回调能正常访问 +- 在WPS365开放平台配置时,只需配置域名(如:`jarvis.van333.cn`),回调路径会自动使用配置中的完整URL + ## API接口说明 ### 1. 获取授权URL @@ -67,13 +73,19 @@ window.open(authUrl, '_blank') ### 2. OAuth回调处理 -**接口**: `GET /jarvis/wps365/oauth/callback` +**接口**: `GET /wps365-callback` **参数**: - `code`: 授权码(由WPS365回调时自动传入) - `state`: 状态参数(可选) +- `error`: 错误码(授权失败时) +- `error_description`: 错误描述(授权失败时) -**说明**: 此接口处理WPS365的授权回调,自动获取并保存Token。 +**说明**: +- 此接口处理WPS365的授权回调,自动获取并保存Token +- 返回HTML页面,显示授权结果 +- 使用 `/wps365-callback` 路径避免前端路由拦截 +- 授权成功后会显示成功页面,3秒后自动关闭窗口 ### 3. 获取Token状态 diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/jarvis/WPS365CallbackController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/jarvis/WPS365CallbackController.java new file mode 100644 index 0000000..aa7c4cc --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/jarvis/WPS365CallbackController.java @@ -0,0 +1,169 @@ +package com.ruoyi.web.controller.jarvis; + +import com.ruoyi.common.annotation.Anonymous; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.jarvis.domain.dto.WPS365TokenInfo; +import com.ruoyi.jarvis.service.IWPS365OAuthService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +/** + * WPS365 OAuth回调控制器 + * 用于处理OAuth回调,避免前端路由拦截 + * + * @author system + */ +@RestController +@RequestMapping("/wps365-callback") +public class WPS365CallbackController extends BaseController { + + private static final Logger log = LoggerFactory.getLogger(WPS365CallbackController.class); + + @Autowired + private IWPS365OAuthService wps365OAuthService; + + /** + * OAuth回调 - 通过授权码获取访问令牌 + * 路径:/wps365-callback + * 注意:在WPS365开放平台只需配置域名:jarvis.van333.cn(不能包含路径) + * 授权URL中的redirect_uri参数会自动使用配置中的完整URL:https://jarvis.van333.cn/wps365-callback + */ + @Anonymous + @GetMapping(produces = MediaType.TEXT_HTML_VALUE) + public String oauthCallback(@RequestParam(value = "code", required = false) String code, + @RequestParam(value = "state", required = false) String state, + @RequestParam(value = "error", required = false) String error, + @RequestParam(value = "error_description", required = false) String errorDescription) { + try { + // 处理授权错误 + if (error != null) { + log.error("WPS365授权失败 - error: {}, error_description: {}", error, errorDescription); + String errorMsg = errorDescription != null ? errorDescription : error; + return generateCallbackHtml(false, "授权失败: " + errorMsg, null); + } + + // 验证授权码 + if (code == null || code.trim().isEmpty()) { + log.error("授权码为空"); + return generateCallbackHtml(false, "授权码不能为空", null); + } + + log.info("收到WPS365授权回调 - code: {}, state: {}", code, state); + + // 使用授权码换取access_token + WPS365TokenInfo tokenInfo = wps365OAuthService.getAccessTokenByCode(code); + + // 验证返回的token信息 + if (tokenInfo == null || tokenInfo.getAccessToken() == null) { + log.error("获取访问令牌失败 - tokenInfo: {}", tokenInfo); + return generateCallbackHtml(false, "获取访问令牌失败,响应数据格式不正确", null); + } + + log.info("成功获取访问令牌 - userId: {}, access_token: {}", + tokenInfo.getUserId(), + tokenInfo.getAccessToken() != null ? tokenInfo.getAccessToken().substring(0, 20) + "..." : "null"); + + // 自动保存token到后端 + try { + if (tokenInfo.getUserId() != null) { + wps365OAuthService.saveToken(tokenInfo.getUserId(), tokenInfo); + log.info("访问令牌已自动保存到后端缓存 - userId: {}", tokenInfo.getUserId()); + } else { + log.warn("userId为空,无法保存Token"); + return generateCallbackHtml(false, "获取用户ID失败,无法保存Token", null); + } + } catch (Exception e) { + log.error("保存访问令牌失败", e); + return generateCallbackHtml(false, "保存访问令牌失败: " + e.getMessage(), null); + } + + return generateCallbackHtml(true, "授权成功,访问令牌已自动保存", tokenInfo); + } catch (Exception e) { + log.error("OAuth回调处理失败", e); + return generateCallbackHtml(false, "授权失败: " + e.getMessage(), null); + } + } + + /** + * 生成回调HTML页面 + */ + private String generateCallbackHtml(boolean success, String message, WPS365TokenInfo tokenInfo) { + StringBuilder html = new StringBuilder(); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append(""); + html.append("WPS365授权").append(success ? "成功" : "失败").append(""); + html.append(""); + html.append(""); + html.append(""); + html.append("
"); + if (success) { + html.append("
"); + html.append("

授权成功

"); + } else { + html.append("
"); + html.append("

授权失败

"); + } + html.append("
").append(message).append("
"); + + // 显示Token信息(仅成功时) + if (success && tokenInfo != null) { + html.append("
"); + html.append("授权信息:
"); + if (tokenInfo.getUserId() != null) { + html.append("用户ID: ").append(tokenInfo.getUserId()).append("
"); + } + if (tokenInfo.getExpiresIn() != null) { + html.append("有效期: ").append(tokenInfo.getExpiresIn()).append(" 秒
"); + } + html.append("
"); + } + + html.append("

窗口将在3秒后自动关闭...

"); + html.append("
"); + html.append(""); + html.append(""); + html.append(""); + return html.toString(); + } +} + diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/jarvis/WPS365Controller.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/jarvis/WPS365Controller.java index 83b7e53..7ac7b8d 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/jarvis/WPS365Controller.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/jarvis/WPS365Controller.java @@ -55,13 +55,15 @@ public class WPS365Controller extends BaseController { } /** - * OAuth回调处理 + * OAuth回调处理(已废弃,请使用 /wps365-callback) + * 保留此接口用于兼容,实际回调请使用 WPS365CallbackController */ @Anonymous @GetMapping("/oauth/callback") public AjaxResult oauthCallback(@RequestParam String code, @RequestParam(required = false) String state) { try { + log.warn("使用已废弃的回调接口 /jarvis/wps365/oauth/callback,建议使用 /wps365-callback"); log.info("收到OAuth回调 - code: {}, state: {}", code, state); // 通过授权码获取访问令牌 diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml index 9f66ffd..81a8c24 100644 --- a/ruoyi-admin/src/main/resources/application-dev.yml +++ b/ruoyi-admin/src/main/resources/application-dev.yml @@ -222,21 +222,5 @@ tencent: # 刷新Token地址(用于通过refresh_token刷新access_token) refresh-token-url: https://docs.qq.com/oauth/v2/token -# WPS365开放平台配置 -# 文档地址:https://open.wps.cn/ -wps365: - # 应用ID(AppId)- 需要在WPS365开放平台申请 - app-id: YOUR_APP_ID - # 应用密钥(AppKey)- 需要在WPS365开放平台申请,注意保密 - app-key: YOUR_APP_KEY - # 授权回调地址(需要在WPS365开放平台配置授权域名) - redirect-uri: https://jarvis.van333.cn/jarvis/wps365/oauth/callback - # API基础地址 - api-base-url: https://open.wps.cn/api/v1 - # OAuth授权地址 - oauth-url: https://open.wps.cn/oauth2/v1/authorize - # 获取Token地址 - token-url: https://open.wps.cn/oauth2/v1/token - # 刷新Token地址 - refresh-token-url: https://open.wps.cn/oauth2/v1/token + diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index bcc471b..b8929b1 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -9,3 +9,20 @@ tencent: push: # 延迟时间(分钟),默认10分钟 minutes: 10 +# WPS365开放平台配置 +# 文档地址:https://open.wps.cn/ +wps365: + # 应用ID(AppId)- 需要在WPS365开放平台申请 + app-id: AK20260114NNQJKV + # 应用密钥(AppKey)- 需要在WPS365开放平台申请,注意保密 + app-key: 4c58bc1642e5e8fa731f75af9370496a + # 授权回调地址(需要在WPS365开放平台配置授权域名) + redirect-uri: https://jarvis.van333.cn/jarvis/wps365/oauth/callback + # API基础地址 + api-base-url: https://open.wps.cn/api/v1 + # OAuth授权地址 + oauth-url: https://open.wps.cn/oauth2/v1/authorize + # 获取Token地址 + token-url: https://open.wps.cn/oauth2/v1/token + # 刷新Token地址 + refresh-token-url: https://open.wps.cn/oauth2/v1/token