模块细化

This commit is contained in:
D 2024-01-16 22:23:43 +08:00
parent f468d57607
commit f377ff993f
21 changed files with 1024 additions and 24 deletions

View File

@ -203,7 +203,7 @@
<!-- 集成第三方登录 -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-third-auth</artifactId>
<artifactId>ruoyi-oauth</artifactId>
<version>${ruoyi.version}</version>
</dependency>
@ -230,7 +230,7 @@
<module>ruoyi-quartz</module>
<module>ruoyi-generator</module>
<module>ruoyi-common</module>
<module>ruoyi-third-auth</module>
<module>ruoyi-oauth</module>
</modules>
<packaging>pom</packaging>

View File

@ -57,7 +57,8 @@
<!-- 集成第三方登录 -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-third-auth</artifactId>
<artifactId>ruoyi-oauth-wx</artifactId>
<version>3.8.7.3.1</version>
</dependency>
</dependencies>

View File

@ -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

View File

@ -55,7 +55,7 @@ spring:
# 国际化资源文件路径
basename: i18n/messages
profiles:
active: druid,mybatis,thirdAuth
active: druid,mybatis,oauth
# 文件上传
servlet:
multipart:

81
ruoyi-oauth/pom.xml Normal file
View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
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">
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>3.8.7.3.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-oauth</artifactId>
<properties>
<ruoyi.version>3.8.7.3.1</ruoyi.version>
</properties>
<description>
第三方认证模块
</description>
<dependencyManagement>
<dependencies>
<!-- 通用工具-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId>
<version>${ruoyi.version}</version>
</dependency>
<!-- 第三方认证通用工具-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-oauth-common</artifactId>
<version>${ruoyi.version}</version>
</dependency>
<!--httpclient-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
<version>1.16.6</version>
</dependency>
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>3.7.4.ALL</version>
</dependency>
<!-- justauth通用认证 -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-oauth-justauth</artifactId>
<version>${ruoyi.version}</version>
</dependency>
<!-- 微信小程序和公众号认证 -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-oauth-wx</artifactId>
<version>${ruoyi.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>ruoyi-oauth-common</module>
<module>ruoyi-oauth-justauth</module>
<module>ruoyi-oauth-wx</module>
</modules>
<packaging>pom</packaging>
</project>

View File

@ -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">
<parent>
<artifactId>ruoyi</artifactId>
<artifactId>ruoyi-oauth</artifactId>
<groupId>com.ruoyi</groupId>
<version>3.8.7.3.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-third-auth</artifactId>
<artifactId>ruoyi-oauth-common</artifactId>
<description>
system系统模块
@ -27,9 +27,7 @@
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
</dependencies>
</project>

View File

@ -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;

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
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">
<parent>
<artifactId>ruoyi-oauth</artifactId>
<groupId>com.ruoyi</groupId>
<version>3.8.7.3.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-oauth-justauth</artifactId>
<description>
system系统模块
</description>
<dependencies>
<!-- 通用工具-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-oauth-common</artifactId>
</dependency>
<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
<version>1.16.6</version>
</dependency>
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -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<AuthUser> 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<AuthToken> 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<AuthToken> 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());
}
}
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
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">
<parent>
<artifactId>ruoyi-oauth</artifactId>
<groupId>com.ruoyi</groupId>
<version>3.8.7.3.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-oauth-wx</artifactId>
<description>
system系统模块
</description>
<dependencies>
<!-- 通用工具-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-oauth-common</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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 {

View File

@ -1,4 +1,4 @@
package com.ruoyi.third.service;
package com.ruoyi.oauth.wx.service;
public interface WxLoginService {
public String doLoginMiniApp(String code);

37
ruoyi-pay/pom.xml Normal file
View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
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">
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>3.8.7.3.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-pay</artifactId>
<properties>
<ruoyi.version>3.8.7.3.1</ruoyi.version>
</properties>
<description>
第三方认证模块
</description>
<dependencyManagement>
<dependencies>
<!-- 通用工具-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId>
<version>${ruoyi.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>ruoyi-pay-sqb</module>
</modules>
<packaging>pom</packaging>
</project>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
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">
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>3.8.7.3.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-oauth</artifactId>
<description>
system系统模块
</description>
<dependencies>
<!-- 通用工具-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -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;
}
}
}

22
sql/oauth.sql Normal file
View File

@ -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平台用户的附带属性部分平台可能没有'
);