RuoYi-Vue-Plus之第三方授权
文档地址:点击这里
项目地址:点击这里
功能介绍:点击这里
第三方授权
要实现第三方授权,不同的第三方需要配置的信息不一样,下面是一部分第三方应用的配置信息。
配置文件
配置类
@Data
@Component
@ConfigurationProperties(prefix = "justauth")
public class SocialProperties {
/**
* 是否启用
*/
private Boolean enabled;
/**
* 授权类型
* SocialLoginConfigProperties已在上图指出
*/
private Map<String, SocialLoginConfigProperties> type;
}
SocialUtils工具类
/**
* 认证授权工具类
*
* @author thiszhc
*/
public class SocialUtils {
private static final AuthRedisStateCache STATE_CACHE = SpringUtils.getBean(AuthRedisStateCache.class);
@SuppressWarnings("unchecked")
public static AuthResponse<AuthUser> loginAuth(String source, String code, String state, SocialProperties socialProperties) throws AuthException {
AuthRequest authRequest = getAuthRequest(source, socialProperties);
AuthCallback callback = new AuthCallback();
callback.setCode(code);
callback.setState(state);
// 实现第三方登录
return authRequest.login(callback);
}
public static AuthRequest getAuthRequest(String source, SocialProperties socialProperties) throws AuthException {
SocialLoginConfigProperties obj = socialProperties.getType().get(source);
if (ObjectUtil.isNull(obj)) {
throw new AuthException("不支持的第三方登录类型");
}
AuthConfig.AuthConfigBuilder builder = AuthConfig.builder()
.clientId(obj.getClientId())
.clientSecret(obj.getClientSecret())
.redirectUri(obj.getRedirectUri());
return switch (source.toLowerCase()) {
case "dingtalk" -> new AuthDingTalkRequest(builder.build(), STATE_CACHE);
case "baidu" -> new AuthBaiduRequest(builder.build(), STATE_CACHE);
case "github" -> new AuthGithubRequest(builder.build(), STATE_CACHE);
case "gitee" -> new AuthGiteeRequest(builder.build(), STATE_CACHE);
case "weibo" -> new AuthWeiboRequest(builder.build(), STATE_CACHE);
case "coding" -> new AuthCodingRequest(builder.build(), STATE_CACHE);
case "oschina" -> new AuthOschinaRequest(builder.build(), STATE_CACHE);
// 支付宝在创建回调地址时,不允许使用localhost或者127.0.0.1,所以这儿的回调地址使用的局域网内的ip
case "alipay_wallet" -> new AuthAlipayRequest(builder.build(), socialProperties.getType().get("alipay_wallet").getAlipayPublicKey(), STATE_CACHE);
case "qq" -> new AuthQqRequest(builder.build(), STATE_CACHE);
case "wechat_open" -> new AuthWeChatOpenRequest(builder.build(), STATE_CACHE);
case "taobao" -> new AuthTaobaoRequest(builder.build(), STATE_CACHE);
case "douyin" -> new AuthDouyinRequest(builder.build(), STATE_CACHE);
case "linkedin" -> new AuthLinkedinRequest(builder.build(), STATE_CACHE);
case "microsoft" -> new AuthMicrosoftRequest(builder.build(), STATE_CACHE);
case "renren" -> new AuthRenrenRequest(builder.build(), STATE_CACHE);
case "stack_overflow" -> new AuthStackOverflowRequest(builder.stackOverflowKey("").build(), STATE_CACHE);
case "huawei" -> new AuthHuaweiRequest(builder.build(), STATE_CACHE);
case "wechat_enterprise" -> new AuthWeChatEnterpriseQrcodeRequest(builder.agentId("").build(), STATE_CACHE);
case "gitlab" -> new AuthGitlabRequest(builder.build(), STATE_CACHE);
case "wechat_mp" -> new AuthWeChatMpRequest(builder.build(), STATE_CACHE);
case "aliyun" -> new AuthAliyunRequest(builder.build(), STATE_CACHE);
case "maxkey" -> new AuthMaxKeyRequest(builder.build(), STATE_CACHE);
default -> throw new AuthException("未获取到有效的Auth配置");
};
}
}
国外平台配置
如果配置的是国外平台授权登录,例如google,修改一下getAuthRequest()方法,在switch语句中加上 case "google" -> new AuthGoogleRequest(builder.build(), STATE_CACHE);
,然后
例如我的微屁恩,选择http/https的ip
或者打开代理设置
请求登录
控制层方法
/**
* 第三方登录请求
*
* @param source 登录来源
* @return 结果
*/
@GetMapping("/binding/{source}")
public R<String> authBinding(@PathVariable("source") String source) {
if (!socialProperties.getEnabled()) {
return R.fail("第三方授权登录已关闭");
}
// 从配置文件中获得信息
SocialLoginConfigProperties obj = socialProperties.getType().get(source);
if (ObjectUtil.isNull(obj)) {
return R.fail(source + "平台账号暂不支持");
}
AuthRequest authRequest = SocialUtils.getAuthRequest(source, socialProperties);
String authorizeUrl = authRequest.authorize(AuthStateUtils.createState());
return R.ok("操作成功", authorizeUrl);
}
分析authRequest.authorize(AuthStateUtils.createState())
AuthStateUtils.createState():生成uuid
进入方法源码:
经过追溯源码,发现该方法主要作用就是构建url以及把uuid缓存到redis中
绑定授权
控制层方法
/**
* 第三方登录回调业务处理 绑定授权
*
* @param loginBody 请求体
* @return 结果
*/
@PostMapping("/social/callback")
public R<Void> socialCallback(@RequestBody SocialLoginBody loginBody) {
if (!socialProperties.getEnabled()) {
return R.fail("第三方授权登录已关闭");
}
// 获取第三方登录信息
AuthResponse<AuthUser> response = SocialUtils.loginAuth(
loginBody.getSource(), loginBody.getSocialCode(),
loginBody.getSocialState(), socialProperties);
AuthUser authUserData = response.getData();
// 判断授权响应是否成功
if (!response.ok()) {
return R.fail(response.getMsg());
}
loginService.socialRegister(authUserData);
return R.ok();
}
当我们需要绑定第三方应用时,会先调用请求登录接口,如果请求成功,然后再调用绑定授权接口。进入到SocialUtils.loginAuth(),然后进入authRequest.login()。
分析Request.login(callback)
进入authRequest.login()源方法
进入getAccessToken()方法
进入getUserInfo()方法
最终咱们可以获取到:将用户信息设置到授权相应类AuthResponse。然后进行下一步的处理:存到数据库中。
取消绑定
从数据库删除 需要取消绑定的用户即可。
RuoYi-Vue-Plus之第三方授权
http://example.com/2024/04/21/RuoYi-Vue-Plus之第三方授权/