From f377ff993fcc50e273e314457ab0825db6dacbaa Mon Sep 17 00:00:00 2001 From: D <3066417822@qq.com> Date: Tue, 16 Jan 2024 22:23:43 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A8=A1=E5=9D=97=E7=BB=86=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 4 +- ruoyi-admin/pom.xml | 3 +- ...on-thirdAuth.yml => application-oauth.yml} | 4 +- .../src/main/resources/application.yml | 2 +- ruoyi-oauth/pom.xml | 81 ++++ .../ruoyi-oauth-common}/pom.xml | 6 +- .../oauth/common}/utils/HttpClientUtil.java | 2 +- ruoyi-oauth/ruoyi-oauth-justauth/pom.xml | 38 ++ .../justauth/controller/OAuthController.java | 114 +++++ .../service/Impl/OAuthServiceImpl.java | 410 ++++++++++++++++++ .../oauth/justauth/service/OAuthService.java | 21 + ruoyi-oauth/ruoyi-oauth-wx/pom.xml | 29 ++ .../oauth/wx}/constant/WxH5Constant.java | 2 +- .../oauth/wx}/constant/WxMiniAppConstant.java | 2 +- .../wx/controller/WxLoginController.java | 10 +- .../wx}/service/Impl/WxLoginServiceImpl.java | 10 +- .../oauth/wx}/service/WxLoginService.java | 2 +- ruoyi-pay/pom.xml | 37 ++ ruoyi-pay/ruoyi-pay-sqb/pom.xml | 28 ++ .../third/service/Impl/SQBServiceImpl.java | 221 ++++++++++ sql/oauth.sql | 22 + 21 files changed, 1024 insertions(+), 24 deletions(-) rename ruoyi-admin/src/main/resources/{application-thirdAuth.yml => application-oauth.yml} (79%) create mode 100644 ruoyi-oauth/pom.xml rename {ruoyi-third-auth => ruoyi-oauth/ruoyi-oauth-common}/pom.xml (87%) rename {ruoyi-third-auth/src/main/java/com/ruoyi/third => ruoyi-oauth/ruoyi-oauth-common/src/main/java/com/ruoyi/oauth/common}/utils/HttpClientUtil.java (99%) create mode 100644 ruoyi-oauth/ruoyi-oauth-justauth/pom.xml create mode 100644 ruoyi-oauth/ruoyi-oauth-justauth/src/main/java/com/ruoyi/oauth/justauth/controller/OAuthController.java create mode 100644 ruoyi-oauth/ruoyi-oauth-justauth/src/main/java/com/ruoyi/oauth/justauth/service/Impl/OAuthServiceImpl.java create mode 100644 ruoyi-oauth/ruoyi-oauth-justauth/src/main/java/com/ruoyi/oauth/justauth/service/OAuthService.java create mode 100644 ruoyi-oauth/ruoyi-oauth-wx/pom.xml rename {ruoyi-third-auth/src/main/java/com/ruoyi/third => ruoyi-oauth/ruoyi-oauth-wx/src/main/java/com/ruoyi/oauth/wx}/constant/WxH5Constant.java (96%) rename {ruoyi-third-auth/src/main/java/com/ruoyi/third => ruoyi-oauth/ruoyi-oauth-wx/src/main/java/com/ruoyi/oauth/wx}/constant/WxMiniAppConstant.java (96%) rename ruoyi-third-auth/src/main/java/com/ruoyi/third/controller/WxLoginService.java => ruoyi-oauth/ruoyi-oauth-wx/src/main/java/com/ruoyi/oauth/wx/controller/WxLoginController.java (80%) rename {ruoyi-third-auth/src/main/java/com/ruoyi/third => ruoyi-oauth/ruoyi-oauth-wx/src/main/java/com/ruoyi/oauth/wx}/service/Impl/WxLoginServiceImpl.java (88%) rename {ruoyi-third-auth/src/main/java/com/ruoyi/third => ruoyi-oauth/ruoyi-oauth-wx/src/main/java/com/ruoyi/oauth/wx}/service/WxLoginService.java (77%) create mode 100644 ruoyi-pay/pom.xml create mode 100644 ruoyi-pay/ruoyi-pay-sqb/pom.xml create mode 100644 ruoyi-pay/ruoyi-pay-sqb/src/main/java/com/ruoyi/third/service/Impl/SQBServiceImpl.java create mode 100644 sql/oauth.sql diff --git a/pom.xml b/pom.xml index c2dbe85..9b26a15 100644 --- a/pom.xml +++ b/pom.xml @@ -203,7 +203,7 @@ com.ruoyi - ruoyi-third-auth + ruoyi-oauth ${ruoyi.version} @@ -230,7 +230,7 @@ ruoyi-quartz ruoyi-generator ruoyi-common - ruoyi-third-auth + ruoyi-oauth pom diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml index a4cfab7..d76c724 100644 --- a/ruoyi-admin/pom.xml +++ b/ruoyi-admin/pom.xml @@ -57,7 +57,8 @@ com.ruoyi - ruoyi-third-auth + ruoyi-oauth-wx + 3.8.7.3.1 diff --git a/ruoyi-admin/src/main/resources/application-thirdAuth.yml b/ruoyi-admin/src/main/resources/application-oauth.yml similarity index 79% rename from ruoyi-admin/src/main/resources/application-thirdAuth.yml rename to ruoyi-admin/src/main/resources/application-oauth.yml index 6fad0e4..638e9c0 100644 --- a/ruoyi-admin/src/main/resources/application-thirdAuth.yml +++ b/ruoyi-admin/src/main/resources/application-oauth.yml @@ -7,6 +7,6 @@ wx: url: https://api.weixin.qq.com/sns/jscode2session h5: open: true - appId: h5AppId - appSecret: h5Secret + appId: wx98501e665b0f0596 + appSecret: wx98501e665b0f0596 url: https://api.weixin.qq.com/sns/oauth2/access_token \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index 9a8fff9..eadb9ea 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -55,7 +55,7 @@ spring: # 国际化资源文件路径 basename: i18n/messages profiles: - active: druid,mybatis,thirdAuth + active: druid,mybatis,oauth # 文件上传 servlet: multipart: diff --git a/ruoyi-oauth/pom.xml b/ruoyi-oauth/pom.xml new file mode 100644 index 0000000..ea72605 --- /dev/null +++ b/ruoyi-oauth/pom.xml @@ -0,0 +1,81 @@ + + + + ruoyi + com.ruoyi + 3.8.7.3.1 + + 4.0.0 + + ruoyi-oauth + + + 3.8.7.3.1 + + + + 第三方认证模块 + + + + + + + com.ruoyi + ruoyi-common + ${ruoyi.version} + + + + + com.ruoyi + ruoyi-oauth-common + ${ruoyi.version} + + + + + org.apache.httpcomponents + httpclient + 4.5.2 + + + + + me.zhyd.oauth + JustAuth + 1.16.6 + + + com.alipay.sdk + alipay-sdk-java + 3.7.4.ALL + + + + + + com.ruoyi + ruoyi-oauth-justauth + ${ruoyi.version} + + + + + com.ruoyi + ruoyi-oauth-wx + ${ruoyi.version} + + + + + + + ruoyi-oauth-common + ruoyi-oauth-justauth + ruoyi-oauth-wx + + pom + \ No newline at end of file diff --git a/ruoyi-third-auth/pom.xml b/ruoyi-oauth/ruoyi-oauth-common/pom.xml similarity index 87% rename from ruoyi-third-auth/pom.xml rename to ruoyi-oauth/ruoyi-oauth-common/pom.xml index 0a75e29..513cd94 100644 --- a/ruoyi-third-auth/pom.xml +++ b/ruoyi-oauth/ruoyi-oauth-common/pom.xml @@ -3,13 +3,13 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - ruoyi + ruoyi-oauth com.ruoyi 3.8.7.3.1 4.0.0 - ruoyi-third-auth + ruoyi-oauth-common system系统模块 @@ -27,9 +27,7 @@ org.apache.httpcomponents httpclient - 4.5.2 - \ No newline at end of file diff --git a/ruoyi-third-auth/src/main/java/com/ruoyi/third/utils/HttpClientUtil.java b/ruoyi-oauth/ruoyi-oauth-common/src/main/java/com/ruoyi/oauth/common/utils/HttpClientUtil.java similarity index 99% rename from ruoyi-third-auth/src/main/java/com/ruoyi/third/utils/HttpClientUtil.java rename to ruoyi-oauth/ruoyi-oauth-common/src/main/java/com/ruoyi/oauth/common/utils/HttpClientUtil.java index 62ba0eb..62b764e 100644 --- a/ruoyi-third-auth/src/main/java/com/ruoyi/third/utils/HttpClientUtil.java +++ b/ruoyi-oauth/ruoyi-oauth-common/src/main/java/com/ruoyi/oauth/common/utils/HttpClientUtil.java @@ -1,4 +1,4 @@ -package com.ruoyi.third.utils; +package com.ruoyi.oauth.common.utils; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; diff --git a/ruoyi-oauth/ruoyi-oauth-justauth/pom.xml b/ruoyi-oauth/ruoyi-oauth-justauth/pom.xml new file mode 100644 index 0000000..c215801 --- /dev/null +++ b/ruoyi-oauth/ruoyi-oauth-justauth/pom.xml @@ -0,0 +1,38 @@ + + + + ruoyi-oauth + com.ruoyi + 3.8.7.3.1 + + 4.0.0 + + ruoyi-oauth-justauth + + + system系统模块 + + + + + + + com.ruoyi + ruoyi-oauth-common + + + + me.zhyd.oauth + JustAuth + 1.16.6 + + + com.alipay.sdk + alipay-sdk-java + + + + + \ No newline at end of file diff --git a/ruoyi-oauth/ruoyi-oauth-justauth/src/main/java/com/ruoyi/oauth/justauth/controller/OAuthController.java b/ruoyi-oauth/ruoyi-oauth-justauth/src/main/java/com/ruoyi/oauth/justauth/controller/OAuthController.java new file mode 100644 index 0000000..0bce3df --- /dev/null +++ b/ruoyi-oauth/ruoyi-oauth-justauth/src/main/java/com/ruoyi/oauth/justauth/controller/OAuthController.java @@ -0,0 +1,114 @@ +package com.ruoyi.oauth.justauth.controller; + +import java.io.IOException; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import com.alibaba.fastjson.JSONObject; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.oauth.justauth.service.OAuthService; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import me.zhyd.oauth.exception.AuthException; +import me.zhyd.oauth.model.AuthCallback; +import me.zhyd.oauth.model.AuthResponse; +import me.zhyd.oauth.model.AuthToken; +import me.zhyd.oauth.model.AuthUser; +import me.zhyd.oauth.request.AuthRequest; +import me.zhyd.oauth.utils.AuthStateUtils; + +/** + * @author yadong.zhang (yadong.zhang0415(a)gmail.com) + * @version 1.0 + * @website https://www.zhyd.me + * @date 2019/2/19 9:28 + * @since 1.8 + */ +@Controller +@RequestMapping("/oauth") +public class OAuthController extends BaseController { + + @Autowired + private OAuthService oAuthServiceImpl; + + @RequestMapping("/render/{source}") + @ResponseBody + public void renderAuth(@PathVariable("source") String source, HttpServletResponse response) throws IOException { + logger.info("进入render:" + source); + AuthRequest authRequest = oAuthServiceImpl.getAuthRequest(source); + String authorizeUrl = authRequest.authorize(AuthStateUtils.createState()); + logger.info(authorizeUrl); + response.sendRedirect(authorizeUrl); + } + + /** + * oauth平台中配置的授权回调地址,以本项目为例,在创建github授权应用时的回调地址应为:http://127.0.0.1:8443/oauth/callback/github + */ + @RequestMapping("/callback/{source}") + public AjaxResult login(@PathVariable("source") String source, AuthCallback callback, + HttpServletRequest request) { + logger.info("进入callback:" + source + " callback params:" + JSONObject.toJSONString(callback)); + AuthRequest authRequest = oAuthServiceImpl.getAuthRequest(source); + AuthResponse response = authRequest.login(callback); + logger.info(JSONObject.toJSONString(response)); + + if (response.ok()) { + oAuthServiceImpl.save(response.getData()); + return success("授权成功!"); + } + return error(response.getMsg()); + } + + @RequestMapping("/revoke/{source}/{uuid}") + @ResponseBody + public AjaxResult revokeAuth(@PathVariable("source") String source, @PathVariable("uuid") String uuid) + throws IOException { + AuthRequest authRequest = oAuthServiceImpl.getAuthRequest(source.toLowerCase()); + + AuthUser user = oAuthServiceImpl.getByUuid(uuid); + if (null == user) { + return error("用户不存在"); + } + AuthResponse response = null; + try { + response = authRequest.revoke(user.getToken()); + if (response.ok()) { + oAuthServiceImpl.remove(user.getUuid()); + return success("用户 [" + user.getUsername() + "] 的 授权状态 已收回!"); + } + return error("用户 [" + user.getUsername() + "] 的 授权状态 收回失败!" + response.getMsg()); + } catch (AuthException e) { + return error(e.getErrorMsg()); + } + } + + @RequestMapping("/refresh/{source}/{uuid}") + @ResponseBody + public AjaxResult refreshAuth(@PathVariable("source") String source, @PathVariable("uuid") String uuid) { + AuthRequest authRequest = oAuthServiceImpl.getAuthRequest(source.toLowerCase()); + + AuthUser user = oAuthServiceImpl.getByUuid(uuid); + if (null == user) { + return error("用户不存在"); + } + AuthResponse response = null; + try { + response = authRequest.refresh(user.getToken()); + if (response.ok()) { + user.setToken(response.getData()); + oAuthServiceImpl.save(user); + return success("用户 [" + user.getUsername() + "] 的 access token 已刷新!新的 accessToken: " + + response.getData().getAccessToken()); + } + return error("用户 [" + user.getUsername() + "] 的 access token 刷新失败!" + response.getMsg()); + } catch (AuthException e) { + return error(e.getErrorMsg()); + } + } +} diff --git a/ruoyi-oauth/ruoyi-oauth-justauth/src/main/java/com/ruoyi/oauth/justauth/service/Impl/OAuthServiceImpl.java b/ruoyi-oauth/ruoyi-oauth-justauth/src/main/java/com/ruoyi/oauth/justauth/service/Impl/OAuthServiceImpl.java new file mode 100644 index 0000000..a0cd78c --- /dev/null +++ b/ruoyi-oauth/ruoyi-oauth-justauth/src/main/java/com/ruoyi/oauth/justauth/service/Impl/OAuthServiceImpl.java @@ -0,0 +1,410 @@ +package com.ruoyi.oauth.justauth.service.Impl; + +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.util.Arrays; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.alibaba.fastjson.JSONObject; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.oauth.justauth.service.OAuthService; +import com.xkcoding.http.config.HttpConfig; + +import me.zhyd.oauth.config.AuthConfig; +import me.zhyd.oauth.enums.scope.AuthBaiduScope; +import me.zhyd.oauth.enums.scope.AuthCodingScope; +import me.zhyd.oauth.enums.scope.AuthFacebookScope; +import me.zhyd.oauth.enums.scope.AuthGiteeScope; +import me.zhyd.oauth.enums.scope.AuthGithubScope; +import me.zhyd.oauth.enums.scope.AuthGitlabScope; +import me.zhyd.oauth.enums.scope.AuthGoogleScope; +import me.zhyd.oauth.enums.scope.AuthHuaweiScope; +import me.zhyd.oauth.enums.scope.AuthMicrosoftScope; +import me.zhyd.oauth.enums.scope.AuthWeiboScope; +import me.zhyd.oauth.exception.AuthException; +import me.zhyd.oauth.model.AuthUser; +import me.zhyd.oauth.request.AuthAlipayRequest; +import me.zhyd.oauth.request.AuthAliyunRequest; +import me.zhyd.oauth.request.AuthBaiduRequest; +import me.zhyd.oauth.request.AuthCodingRequest; +import me.zhyd.oauth.request.AuthCsdnRequest; +import me.zhyd.oauth.request.AuthDingTalkRequest; +import me.zhyd.oauth.request.AuthDouyinRequest; +import me.zhyd.oauth.request.AuthElemeRequest; +import me.zhyd.oauth.request.AuthFacebookRequest; +import me.zhyd.oauth.request.AuthFeishuRequest; +import me.zhyd.oauth.request.AuthGiteeRequest; +import me.zhyd.oauth.request.AuthGithubRequest; +import me.zhyd.oauth.request.AuthGitlabRequest; +import me.zhyd.oauth.request.AuthGoogleRequest; +import me.zhyd.oauth.request.AuthHuaweiRequest; +import me.zhyd.oauth.request.AuthKujialeRequest; +import me.zhyd.oauth.request.AuthLinkedinRequest; +import me.zhyd.oauth.request.AuthMeituanRequest; +import me.zhyd.oauth.request.AuthMiRequest; +import me.zhyd.oauth.request.AuthMicrosoftRequest; +import me.zhyd.oauth.request.AuthOschinaRequest; +import me.zhyd.oauth.request.AuthPinterestRequest; +import me.zhyd.oauth.request.AuthQqRequest; +import me.zhyd.oauth.request.AuthRenrenRequest; +import me.zhyd.oauth.request.AuthRequest; +import me.zhyd.oauth.request.AuthStackOverflowRequest; +import me.zhyd.oauth.request.AuthTaobaoRequest; +import me.zhyd.oauth.request.AuthTeambitionRequest; +import me.zhyd.oauth.request.AuthToutiaoRequest; +import me.zhyd.oauth.request.AuthTwitterRequest; +import me.zhyd.oauth.request.AuthWeChatEnterpriseQrcodeRequest; +import me.zhyd.oauth.request.AuthWeChatMpRequest; +import me.zhyd.oauth.request.AuthWeChatOpenRequest; +import me.zhyd.oauth.request.AuthWeiboRequest; +import me.zhyd.oauth.request.AuthXmlyRequest; +import me.zhyd.oauth.utils.AuthScopeUtils; + +public class OAuthServiceImpl implements OAuthService { + + @Autowired + private RedisCache redisCache; + + @Override + public AuthUser save(AuthUser user) { + redisCache.setCacheObject(user.getUuid(), user); + return user; + } + + @Override + public AuthUser getByUuid(String uuid) { + Object user = redisCache.getCacheObject(uuid); + if (null == user) { + return null; + } + return JSONObject.parseObject(JSONObject.toJSONString(user), AuthUser.class); + } + + @Override + public void remove(String uuid) { + redisCache.deleteObject(uuid); + } + + /** + * 根据具体的授权来源,获取授权请求工具类 + * + * @param source + * @return + */ + public AuthRequest getAuthRequest(String source) { + AuthRequest authRequest = null; + switch (source.toLowerCase()) { + case "dingtalk": + authRequest = new AuthDingTalkRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://localhost:8443/oauth/callback/dingtalk") + .build()); + break; + case "baidu": + authRequest = new AuthBaiduRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://localhost:8443/oauth/callback/baidu") + .scopes(Arrays.asList( + AuthBaiduScope.BASIC.getScope(), + AuthBaiduScope.SUPER_MSG.getScope(), + AuthBaiduScope.NETDISK.getScope())) + .build()); + break; + case "github": + authRequest = new AuthGithubRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://localhost:8443/oauth/callback/github") + .scopes(AuthScopeUtils.getScopes(AuthGithubScope.values())) + // 针对国外平台配置代理 + .httpConfig(HttpConfig.builder() + .timeout(15000) + .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 10080))) + .build()) + .build()); + break; + case "gitee": + authRequest = new AuthGiteeRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://127.0.0.1:8443/oauth/callback/gitee") + .scopes(AuthScopeUtils.getScopes(AuthGiteeScope.values())) + .build()); + break; + case "weibo": + authRequest = new AuthWeiboRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://dblog-web.zhyd.me/oauth/callback/weibo") + .scopes(Arrays.asList( + AuthWeiboScope.EMAIL.getScope(), + AuthWeiboScope.FRIENDSHIPS_GROUPS_READ.getScope(), + AuthWeiboScope.STATUSES_TO_ME_READ.getScope())) + .build()); + break; + case "coding": + authRequest = new AuthCodingRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://dblog-web.zhyd.me/oauth/callback/coding") + .domainPrefix("") + .scopes(Arrays.asList( + AuthCodingScope.USER.getScope(), + AuthCodingScope.USER_EMAIL.getScope(), + AuthCodingScope.USER_PHONE.getScope())) + .build()); + break; + case "oschina": + authRequest = new AuthOschinaRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://localhost:8443/oauth/callback/oschina") + .build()); + break; + case "alipay": + // 支付宝在创建回调地址时,不允许使用localhost或者127.0.0.1,所以这儿的回调地址使用的局域网内的ip + authRequest = new AuthAlipayRequest(AuthConfig.builder() + .clientId("APPID") + .clientSecret("应用私钥") + .alipayPublicKey("支付宝公钥") + .redirectUri("https://www.zhyd.me/oauth/callback/alipay") + .build()); + break; + case "qq": + authRequest = new AuthQqRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://localhost:8443/oauth/callback/qq") + .build()); + break; + case "wechat_open": + authRequest = new AuthWeChatOpenRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://www.zhyd.me/oauth/callback/wechat") + .build()); + break; + case "csdn": + authRequest = new AuthCsdnRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://dblog-web.zhyd.me/oauth/callback/csdn") + .build()); + break; + case "taobao": + authRequest = new AuthTaobaoRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://dblog-web.zhyd.me/oauth/callback/taobao") + .build()); + break; + case "google": + authRequest = new AuthGoogleRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://localhost:8443/oauth/callback/google") + .scopes(AuthScopeUtils.getScopes(AuthGoogleScope.USER_EMAIL, AuthGoogleScope.USER_PROFILE, + AuthGoogleScope.USER_OPENID)) + // 针对国外平台配置代理 + .httpConfig(HttpConfig.builder() + .timeout(15000) + .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 10080))) + .build()) + .build()); + break; + case "facebook": + authRequest = new AuthFacebookRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("https://justauth.cn/oauth/callback/facebook") + .scopes(AuthScopeUtils.getScopes(AuthFacebookScope.values())) + // 针对国外平台配置代理 + .httpConfig(HttpConfig.builder() + .timeout(15000) + .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 10080))) + .build()) + .build()); + break; + case "douyin": + authRequest = new AuthDouyinRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://dblog-web.zhyd.me/oauth/callback/douyin") + .build()); + break; + case "linkedin": + authRequest = new AuthLinkedinRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://localhost:8443/oauth/callback/linkedin") + .scopes(null) + .build()); + break; + case "microsoft": + authRequest = new AuthMicrosoftRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://localhost:8443/oauth/callback/microsoft") + .scopes(Arrays.asList( + AuthMicrosoftScope.USER_READ.getScope(), + AuthMicrosoftScope.USER_READWRITE.getScope(), + AuthMicrosoftScope.USER_READBASIC_ALL.getScope(), + AuthMicrosoftScope.USER_READ_ALL.getScope(), + AuthMicrosoftScope.USER_READWRITE_ALL.getScope(), + AuthMicrosoftScope.USER_INVITE_ALL.getScope(), + AuthMicrosoftScope.USER_EXPORT_ALL.getScope(), + AuthMicrosoftScope.USER_MANAGEIDENTITIES_ALL.getScope(), + AuthMicrosoftScope.FILES_READ.getScope())) + .build()); + break; + case "mi": + authRequest = new AuthMiRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://dblog-web.zhyd.me/oauth/callback/mi") + .build()); + break; + case "toutiao": + authRequest = new AuthToutiaoRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://dblog-web.zhyd.me/oauth/callback/toutiao") + .build()); + break; + case "teambition": + authRequest = new AuthTeambitionRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://127.0.0.1:8443/oauth/callback/teambition") + .build()); + break; + case "pinterest": + authRequest = new AuthPinterestRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("https://eadmin.innodev.com.cn/oauth/callback/pinterest") + // 针对国外平台配置代理 + .httpConfig(HttpConfig.builder() + .timeout(15000) + .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 10080))) + .build()) + .build()); + break; + case "renren": + authRequest = new AuthRenrenRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://127.0.0.1:8443/oauth/callback/teambition") + .build()); + break; + case "stack_overflow": + authRequest = new AuthStackOverflowRequest(AuthConfig.builder() + .clientId("") + .clientSecret("((") + .redirectUri("http://localhost:8443/oauth/callback/stack_overflow") + .stackOverflowKey("") + .build()); + break; + case "huawei": + authRequest = new AuthHuaweiRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://127.0.0.1:8443/oauth/callback/huawei") + .scopes(Arrays.asList( + AuthHuaweiScope.BASE_PROFILE.getScope(), + AuthHuaweiScope.MOBILE_NUMBER.getScope(), + AuthHuaweiScope.ACCOUNTLIST.getScope(), + AuthHuaweiScope.SCOPE_DRIVE_FILE.getScope(), + AuthHuaweiScope.SCOPE_DRIVE_APPDATA.getScope())) + .build()); + break; + case "wechat_enterprise": + authRequest = new AuthWeChatEnterpriseQrcodeRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://justauth.cn/oauth/callback/wechat_enterprise") + .agentId("1000003") + .build()); + break; + case "kujiale": + authRequest = new AuthKujialeRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://dblog-web.zhyd.me/oauth/callback/kujiale") + .build()); + break; + case "gitlab": + authRequest = new AuthGitlabRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://localhost:8443/oauth/callback/gitlab") + .scopes(AuthScopeUtils.getScopes(AuthGitlabScope.values())) + .build()); + break; + case "meituan": + authRequest = new AuthMeituanRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://localhost:8443/oauth/callback/meituan") + .build()); + break; + case "eleme": + authRequest = new AuthElemeRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://dblog-web.zhyd.me/oauth/callback/eleme") + .build()); + break; + case "twitter": + authRequest = new AuthTwitterRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("https://threelogin.31huiyi.com/oauth/callback/twitter") + // 针对国外平台配置代理 + .httpConfig(HttpConfig.builder() + .timeout(15000) + .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 10080))) + .build()) + .build()); + break; + case "wechat_mp": + authRequest = new AuthWeChatMpRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("") + .build()); + break; + case "aliyun": + authRequest = new AuthAliyunRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://localhost:8443/oauth/callback/aliyun") + .build()); + break; + case "xmly": + authRequest = new AuthXmlyRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://localhost:8443/oauth/callback/xmly") + .build()); + break; + case "feishu": + authRequest = new AuthFeishuRequest(AuthConfig.builder() + .clientId("") + .clientSecret("") + .redirectUri("http://localhost:8443/oauth/callback/feishu") + .build()); + break; + default: + break; + } + if (null == authRequest) { + throw new AuthException("未获取到有效的Auth配置"); + } + return authRequest; + } + +} diff --git a/ruoyi-oauth/ruoyi-oauth-justauth/src/main/java/com/ruoyi/oauth/justauth/service/OAuthService.java b/ruoyi-oauth/ruoyi-oauth-justauth/src/main/java/com/ruoyi/oauth/justauth/service/OAuthService.java new file mode 100644 index 0000000..cb0e707 --- /dev/null +++ b/ruoyi-oauth/ruoyi-oauth-justauth/src/main/java/com/ruoyi/oauth/justauth/service/OAuthService.java @@ -0,0 +1,21 @@ +package com.ruoyi.oauth.justauth.service; + +import me.zhyd.oauth.model.AuthUser; +import me.zhyd.oauth.request.AuthRequest; + +public interface OAuthService { + /** + * 根据具体的授权来源,获取授权请求工具类 + * + * @param source + * @return + */ + public AuthRequest getAuthRequest(String source); + + AuthUser save(AuthUser user); + + AuthUser getByUuid(String uuid); + + void remove(String uuid); + +} diff --git a/ruoyi-oauth/ruoyi-oauth-wx/pom.xml b/ruoyi-oauth/ruoyi-oauth-wx/pom.xml new file mode 100644 index 0000000..b404da6 --- /dev/null +++ b/ruoyi-oauth/ruoyi-oauth-wx/pom.xml @@ -0,0 +1,29 @@ + + + + ruoyi-oauth + com.ruoyi + 3.8.7.3.1 + + 4.0.0 + + ruoyi-oauth-wx + + + system系统模块 + + + + + + + com.ruoyi + ruoyi-oauth-common + + + + + + \ No newline at end of file diff --git a/ruoyi-third-auth/src/main/java/com/ruoyi/third/constant/WxH5Constant.java b/ruoyi-oauth/ruoyi-oauth-wx/src/main/java/com/ruoyi/oauth/wx/constant/WxH5Constant.java similarity index 96% rename from ruoyi-third-auth/src/main/java/com/ruoyi/third/constant/WxH5Constant.java rename to ruoyi-oauth/ruoyi-oauth-wx/src/main/java/com/ruoyi/oauth/wx/constant/WxH5Constant.java index 150cefe..1ba8217 100644 --- a/ruoyi-third-auth/src/main/java/com/ruoyi/third/constant/WxH5Constant.java +++ b/ruoyi-oauth/ruoyi-oauth-wx/src/main/java/com/ruoyi/oauth/wx/constant/WxH5Constant.java @@ -1,4 +1,4 @@ -package com.ruoyi.third.constant; +package com.ruoyi.oauth.wx.constant; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; diff --git a/ruoyi-third-auth/src/main/java/com/ruoyi/third/constant/WxMiniAppConstant.java b/ruoyi-oauth/ruoyi-oauth-wx/src/main/java/com/ruoyi/oauth/wx/constant/WxMiniAppConstant.java similarity index 96% rename from ruoyi-third-auth/src/main/java/com/ruoyi/third/constant/WxMiniAppConstant.java rename to ruoyi-oauth/ruoyi-oauth-wx/src/main/java/com/ruoyi/oauth/wx/constant/WxMiniAppConstant.java index b00ff85..3e0920f 100644 --- a/ruoyi-third-auth/src/main/java/com/ruoyi/third/constant/WxMiniAppConstant.java +++ b/ruoyi-oauth/ruoyi-oauth-wx/src/main/java/com/ruoyi/oauth/wx/constant/WxMiniAppConstant.java @@ -1,4 +1,4 @@ -package com.ruoyi.third.constant; +package com.ruoyi.oauth.wx.constant; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; diff --git a/ruoyi-third-auth/src/main/java/com/ruoyi/third/controller/WxLoginService.java b/ruoyi-oauth/ruoyi-oauth-wx/src/main/java/com/ruoyi/oauth/wx/controller/WxLoginController.java similarity index 80% rename from ruoyi-third-auth/src/main/java/com/ruoyi/third/controller/WxLoginService.java rename to ruoyi-oauth/ruoyi-oauth-wx/src/main/java/com/ruoyi/oauth/wx/controller/WxLoginController.java index f167adf..4bf6562 100644 --- a/ruoyi-third-auth/src/main/java/com/ruoyi/third/controller/WxLoginService.java +++ b/ruoyi-oauth/ruoyi-oauth-wx/src/main/java/com/ruoyi/oauth/wx/controller/WxLoginController.java @@ -1,4 +1,4 @@ -package com.ruoyi.third.controller; +package com.ruoyi.oauth.wx.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; @@ -9,13 +9,13 @@ import org.springframework.web.bind.annotation.RestController; import com.ruoyi.common.annotation.Anonymous; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.third.constant.WxH5Constant; -import com.ruoyi.third.constant.WxMiniAppConstant; -import com.ruoyi.third.service.Impl.WxLoginServiceImpl;; +import com.ruoyi.oauth.wx.constant.WxH5Constant; +import com.ruoyi.oauth.wx.constant.WxMiniAppConstant; +import com.ruoyi.oauth.wx.service.Impl.WxLoginServiceImpl; @RestController @RequestMapping("/wx") -public class WxLoginService extends BaseController { +public class WxLoginController extends BaseController { @Autowired public WxH5Constant wxH5AppConstant; diff --git a/ruoyi-third-auth/src/main/java/com/ruoyi/third/service/Impl/WxLoginServiceImpl.java b/ruoyi-oauth/ruoyi-oauth-wx/src/main/java/com/ruoyi/oauth/wx/service/Impl/WxLoginServiceImpl.java similarity index 88% rename from ruoyi-third-auth/src/main/java/com/ruoyi/third/service/Impl/WxLoginServiceImpl.java rename to ruoyi-oauth/ruoyi-oauth-wx/src/main/java/com/ruoyi/oauth/wx/service/Impl/WxLoginServiceImpl.java index 4c560c9..bab2f50 100644 --- a/ruoyi-third-auth/src/main/java/com/ruoyi/third/service/Impl/WxLoginServiceImpl.java +++ b/ruoyi-oauth/ruoyi-oauth-wx/src/main/java/com/ruoyi/oauth/wx/service/Impl/WxLoginServiceImpl.java @@ -1,4 +1,4 @@ -package com.ruoyi.third.service.Impl; +package com.ruoyi.oauth.wx.service.Impl; import java.util.HashMap; import java.util.Map; @@ -9,10 +9,10 @@ import org.springframework.stereotype.Service; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.ruoyi.common.exception.ServiceException; -import com.ruoyi.third.constant.WxH5Constant; -import com.ruoyi.third.constant.WxMiniAppConstant; -import com.ruoyi.third.service.WxLoginService; -import com.ruoyi.third.utils.HttpClientUtil; +import com.ruoyi.oauth.common.utils.HttpClientUtil; +import com.ruoyi.oauth.wx.constant.WxH5Constant; +import com.ruoyi.oauth.wx.constant.WxMiniAppConstant; +import com.ruoyi.oauth.wx.service.WxLoginService; @Service public class WxLoginServiceImpl implements WxLoginService { diff --git a/ruoyi-third-auth/src/main/java/com/ruoyi/third/service/WxLoginService.java b/ruoyi-oauth/ruoyi-oauth-wx/src/main/java/com/ruoyi/oauth/wx/service/WxLoginService.java similarity index 77% rename from ruoyi-third-auth/src/main/java/com/ruoyi/third/service/WxLoginService.java rename to ruoyi-oauth/ruoyi-oauth-wx/src/main/java/com/ruoyi/oauth/wx/service/WxLoginService.java index 244a143..35333cf 100644 --- a/ruoyi-third-auth/src/main/java/com/ruoyi/third/service/WxLoginService.java +++ b/ruoyi-oauth/ruoyi-oauth-wx/src/main/java/com/ruoyi/oauth/wx/service/WxLoginService.java @@ -1,4 +1,4 @@ -package com.ruoyi.third.service; +package com.ruoyi.oauth.wx.service; public interface WxLoginService { public String doLoginMiniApp(String code); diff --git a/ruoyi-pay/pom.xml b/ruoyi-pay/pom.xml new file mode 100644 index 0000000..2442c17 --- /dev/null +++ b/ruoyi-pay/pom.xml @@ -0,0 +1,37 @@ + + + + ruoyi + com.ruoyi + 3.8.7.3.1 + + 4.0.0 + + ruoyi-pay + + + 3.8.7.3.1 + + + + 第三方认证模块 + + + + + + com.ruoyi + ruoyi-common + ${ruoyi.version} + + + + + + + ruoyi-pay-sqb + + pom + \ No newline at end of file diff --git a/ruoyi-pay/ruoyi-pay-sqb/pom.xml b/ruoyi-pay/ruoyi-pay-sqb/pom.xml new file mode 100644 index 0000000..0e57d0f --- /dev/null +++ b/ruoyi-pay/ruoyi-pay-sqb/pom.xml @@ -0,0 +1,28 @@ + + + + ruoyi + com.ruoyi + 3.8.7.3.1 + + 4.0.0 + + ruoyi-oauth + + + system系统模块 + + + + + + + com.ruoyi + ruoyi-common + + + + + \ No newline at end of file diff --git a/ruoyi-pay/ruoyi-pay-sqb/src/main/java/com/ruoyi/third/service/Impl/SQBServiceImpl.java b/ruoyi-pay/ruoyi-pay-sqb/src/main/java/com/ruoyi/third/service/Impl/SQBServiceImpl.java new file mode 100644 index 0000000..9838f9f --- /dev/null +++ b/ruoyi-pay/ruoyi-pay-sqb/src/main/java/com/ruoyi/third/service/Impl/SQBServiceImpl.java @@ -0,0 +1,221 @@ +package org.jeecg.modules.sqb.service.impl; + + +import org.json.JSONObject; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Service; +import java.net.URLEncoder; +import java.net.URLDecoder; + +import java.io.UnsupportedEncodingException; +import java.util.Random; + +@Service +@PropertySource("classpath:sqbpay.properties") +@ConfigurationProperties(prefix = "sqbpay") +@Data +public class SQBServiceImpl { + private String apiDomain; + private String terminalSn; + private String terminalKey; + private String appId; + private String vendorSn; + private String vendorKey; + private final static String CHARSET_UTF8 = "utf8"; + + /** + * 计算字符串的MD5值 + * + * @param signStr:签名字符串 + * @return + */ + public String getSign(String signStr) { + try { + String md5 = MD5Util.encryptMd5(signStr); + return md5; + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 终端激活 + * + * @param code:激活码 + * @return {terminal_sn:"$终端号",terminal_key:"$终端密钥"} + */ + public JSONObject activate(String code, String deviceId, String clientSn, String name) { + String url = apiDomain + "/terminal/activate"; + JSONObject params = new JSONObject(); + try { + params.put("app_id", appId); // app_id,必填 + params.put("code", code); // 激活码,必填 + params.put("device_id", deviceId); // 客户方收银终端序列号,需保证同一app_id下唯一,必填。为方便识别,建议格式为“品牌名+门店编号+‘POS’+POS编号“ + params.put("client_sn", clientSn); // 客户方终端编号,一般客户方或系统给收银终端的编号,必填 + params.put("name", name); // 客户方终端名称,必填 + + String sign = getSign(params.toString() + vendorKey); + System.out.println(params.toString() + vendorKey); + String result = HttpUtil.httpPost(url, params.toString(), sign, vendorSn); + JSONObject retObj = new JSONObject(result); + String resCode = retObj.get("result_code").toString(); + if (!resCode.equals("200")) + return null; + String responseStr = retObj.get("biz_response").toString(); + JSONObject terminal = new JSONObject(responseStr); + if (terminal.get("terminal_sn") == null || terminal.get("terminal_key") == null) + return null; + return terminal; + } catch (Exception e) { + return null; + } + } + + /** + * 终端签到 + * + * @return {terminal_sn:"$终端号",terminal_key:"$终端密钥"} + */ + public JSONObject checkin() { + String url = apiDomain + "/terminal/checkin"; + JSONObject params = new JSONObject(); + try { + params.put("terminal_sn", terminalSn); + params.put("device_id", "HUISUAN001POS01"); + params.put("os_info", "Mac OS"); + params.put("sdk_version", "Java SDK v1.0"); + String sign = getSign(params.toString() + terminalKey); + String result = HttpUtil.httpPost(url, params.toString(), sign, terminalSn); + JSONObject retObj = new JSONObject(result); + String resCode = retObj.get("result_code").toString(); + if (!resCode.equals("200")) + return null; + String responseStr = retObj.get("biz_response").toString(); + JSONObject terminal = new JSONObject(responseStr); + if (terminal.get("terminal_sn") == null || terminal.get("terminal_key") == null) + return null; + return terminal; + } catch (Exception e) { + return null; + } + } + + /** + * 退款 + * + * @return + */ + public String refund(SageOrder orderPay) { + String url = apiDomain + "/upay/v2/refund"; + JSONObject params = new JSONObject(); + try { + params.put("terminal_sn", terminalSn); // 收钱吧终端ID + params.put("client_sn", orderPay.getSn()); // 商户系统订单号,必须在商户系统内唯一;且长度不超过64字节 + params.put("refund_amount", orderPay.getTotalAmount()); // 退款金额 + params.put("refund_request_no", "2"); // 商户退款所需序列号,表明是第几次退款 + params.put("operator", "kay"); // 门店操作员 + + String sign = getSign(params.toString() + terminalKey); + String result = HttpUtil.httpPost(url, params.toString(), sign, terminalSn); + + return result; + } catch (Exception e) { + return null; + } + } + + /** + * 查询 + * + * @return + */ + public String query(SageOrder orderPay) { + String url = apiDomain + "/upay/v2/query"; + JSONObject params = new JSONObject(); + try { + params.put("terminal_sn", terminalSn); // 终端号 + params.put("client_sn", orderPay.getSn()); // 商户系统订单号,必须在商户系统内唯一;且长度不超过64字节 + System.out.println(params.toString() + terminalKey); + String sign = getSign(params.toString() + terminalKey); + String result = HttpUtil.httpPost(url, params.toString(), sign, terminalSn); + JSONObject retObj = new JSONObject(result); + String resCode = retObj.get("result_code").toString(); + if (!resCode.equals("200")) + return null; + String responseStr = retObj.get("biz_response").toString(); + return responseStr; + } catch (Exception e) { + return null; + } + } + + public String payUrl(SageOrder orderPay) throws UnsupportedEncodingException { + String param = "" + + "client_sn=" + orderPay.getSn() + + "&operator=" + orderPay.getOperator() + + "&return_url=" + "https://www.shouqianba.com/" + + "&subject=" + orderPay.getSubject() + + "&terminal_sn=" + terminalSn + + "&total_amount=" + orderPay.getTotalAmount(); + String urlParam = "" + + "client_sn=" + orderPay.getSn() + + "&operator=" + URLEncoder.encode(orderPay.getOperator(), "UTF-8") + + "&return_url=" + "https://www.shouqianba.com/" + + "&subject=" + URLEncoder.encode(orderPay.getSubject(), "UTF-8") + + "&terminal_sn=" + terminalSn + + "&total_amount=" + orderPay.getTotalAmount(); + String sign = getSign(param + "&key=" + terminalKey); + return "https://qr.shouqianba.com/gateway?" + urlParam + "&sign=" + sign.toUpperCase(); + } + + /** + * 预下单 + * + * @return + */ + public String precreate(SageOrder orderPay) { + String url = apiDomain + "/upay/v2/precreate"; + JSONObject params = new JSONObject(); + try { + params.put("terminal_sn", terminalSn); // 收钱吧终端ID + params.put("client_sn", orderPay.getSn()); // 商户系统订单号,必须在商户系统内唯一;且长度不超过32字节 + params.put("total_amount", orderPay.getTotalAmount()); // 交易总金额 + params.put("payway", orderPay.getPayway()); // 支付方式 + params.put("subject", orderPay.getSubject()); // 交易简介 + params.put("operator", orderPay.getOperator()); // 门店操作员 + + String sign = getSign(params.toString() + terminalKey); + String result = HttpUtil.httpPost(url, params.toString(), sign, terminalSn); + return result; + } catch (Exception e) { + return null; + } + } + + /** + * 自动撤单 + * + * @param terminal_sn:终端号 + * @param terminal_key:终端密钥 + * @return + */ + public String cancel(String terminal_sn, String terminal_key) { + String url = apiDomain + "/upay/v2/cancel"; + JSONObject params = new JSONObject(); + try { + params.put("terminal_sn", terminal_sn); // 终端号 + params.put("sn", "7892259488292938"); // 收钱吧系统内部唯一订单号 + params.put("client_sn", "18348290098298292838"); // 商户系统订单号,必须在商户系统内唯一;且长度不超过64字节 + + String sign = getSign(params.toString() + terminal_key); + String result = HttpUtil.httpPost(url, params.toString(), sign, terminal_sn); + + return result; + } catch (Exception e) { + return null; + } + } + +} diff --git a/sql/oauth.sql b/sql/oauth.sql new file mode 100644 index 0000000..e90e3dd --- /dev/null +++ b/sql/oauth.sql @@ -0,0 +1,22 @@ +DROP TABLE IF EXISTS oauth_user; +CREATE TABLE oauth_user ( + id INT PRIMARY KEY COMMENT '主键', + uuid VARCHAR(255) NOT NULL COMMENT '第三方系统的唯一ID,详细解释请参考:名词解释', + user_id bigint(20) NOT NULL comment '用户ID', + source VARCHAR(255) NOT NULL COMMENT '第三方用户来源,可选值:GITHUB、GITEE、QQ,更多请参考:AuthDefaultSource.java(opens new window)', + access_token VARCHAR(255) NOT NULL COMMENT '用户的授权令牌', + expire_in INT COMMENT '第三方用户的授权令牌的有效期,部分平台可能没有', + refresh_token VARCHAR(255) COMMENT '刷新令牌,部分平台可能没有', + open_id VARCHAR(255) COMMENT '第三方用户的 open id,部分平台可能没有', + uid VARCHAR(255) COMMENT '第三方用户的 ID,部分平台可能没有', + access_code VARCHAR(255) COMMENT '个别平台的授权信息,部分平台可能没有', + union_id VARCHAR(255) COMMENT '第三方用户的 union id,部分平台可能没有', + scope VARCHAR(255) COMMENT '第三方用户授予的权限,部分平台可能没有', + token_type VARCHAR(255) COMMENT '个别平台的授权信息,部分平台可能没有', + id_token VARCHAR(255) COMMENT 'id token,部分平台可能没有', + mac_algorithm VARCHAR(255) COMMENT '小米平台用户的附带属性,部分平台可能没有', + mac_key VARCHAR(255) COMMENT '小米平台用户的附带属性,部分平台可能没有', + code VARCHAR(255) COMMENT '用户的授权code,部分平台可能没有', + oauth_token VARCHAR(255) COMMENT 'Twitter平台用户的附带属性,部分平台可能没有', + oauth_token_secret VARCHAR(255) COMMENT 'Twitter平台用户的附带属性,部分平台可能没有' +); \ No newline at end of file