1
0
mirror of https://gitee.com/bookshelfplus/bookshelfplus synced 2025-09-19 00:10:39 +08:00
Code Issues Projects Releases Wiki Activity GitHub Gitee
Files
bookshelfplus/bookshelfplus/src/main/java/plus/bookshelf/Controller/Controller/ThirdPartyController.java

148 lines
7.7 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package plus.bookshelf.Controller.Controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.request.*;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import plus.bookshelf.Common.Error.BusinessErrorCode;
import plus.bookshelf.Common.Error.BusinessException;
import plus.bookshelf.Common.Response.CommonReturnType;
import plus.bookshelf.Config.ThirdPartyConfig;
import plus.bookshelf.Controller.VO.UserVO;
import plus.bookshelf.Service.Impl.ThirdPartyUserServiceImpl;
import plus.bookshelf.Service.Model.ThirdPartyUserModel;
import plus.bookshelf.Service.Model.UserModel;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
@Api(tags = "第三方登录")
@Controller
@RequestMapping("/third-party")
public class ThirdPartyController extends BaseController {
// refer document: https://justauth.wiki/guide/
// Gitee: https://justauth.wiki/guide/oauth/gitee
// state在OAuth的流程中的主要作用就是保证请求完整性防止CSRF风险此处传的state将在回调时传回
@Autowired
private ThirdPartyConfig thirdPartyConfig;
@Autowired
ThirdPartyUserServiceImpl thirdPartyUserService;
@ApiOperation(value = "第三方用户登录跳转地址", notes = "传入需要登录的第三方平台大小写均可返回跳转url")
@RequestMapping(value = "login", method = {RequestMethod.GET})
@ResponseBody
public CommonReturnType login(@RequestParam(value = "platform") String platform) throws BusinessException {
AuthRequest authRequest = getAuthRequest(platform);
String authorizeUrl = authRequest.authorize(AuthStateUtils.createState());
return CommonReturnType.create(authorizeUrl);
}
@ApiOperation(value = "快捷登录回调函数", notes = "如果传入 token 那么就是绑定第三方账号到当前登录账号,否则就是通过第三方授权登录")
@RequestMapping(value = "callback/{platform}", method = {RequestMethod.GET})
@ResponseBody
public CommonReturnType callback(@PathVariable("platform") String platform,
@RequestParam(value = "token", required = false) String token,
AuthCallback callback) throws BusinessException {
AuthRequest authRequest = getAuthRequest(platform);
AuthResponse authResponse;
try {
authResponse = authRequest.login(callback);
} catch (AuthException e) {
// [ERROR] - Failed to login with oauth authorization.
throw new BusinessException(BusinessErrorCode.THIRD_PARTY_LOGIN_FAIL, "第三方登录失败");
}
if (token == null || token.isEmpty()) {
// 通过第三方授权登录
UserModel userModel = thirdPartyUserService.loginCallback(authResponse);
UserVO userVO = UserController.convertFromService(userModel);
if (userModel != null) {
String userLoginToken = onLogin(userModel);
userVO.setToken(userLoginToken); // token 仅在用户登录时传一次,后面获取用户状态接口中不重复返回 token 信息
}
return CommonReturnType.create(userVO);
} else {
// 绑定第三方账号到当前登录账号
Boolean isSuccess = thirdPartyUserService.bindThirdPartAccountCallback(authResponse, token);
return CommonReturnType.create(isSuccess);
}
}
@ApiOperation(value = "【用户|管理员】获取用户已绑定的第三方平台", notes = "传入当前登录用户 token ,返回已绑定的第三方平台")
@RequestMapping(value = "getBindingStatus", method = {RequestMethod.GET})
@ResponseBody
public CommonReturnType getBindingStatus(@RequestParam(value = "token", required = false) String token) throws BusinessException, InvocationTargetException, IllegalAccessException {
List<ThirdPartyUserModel> bindingStatus = thirdPartyUserService.getBindingStatus(token);
List<String> bindingPlatformList = new ArrayList<>();
for (ThirdPartyUserModel thirdPartyUserModel : bindingStatus) {
bindingPlatformList.add(thirdPartyUserModel.getSource());
}
return CommonReturnType.create(bindingPlatformList);
}
@ApiOperation(value = "【用户|管理员】取消第三方平台绑定", notes = "传入当前登录用户 token 和平台 platform (不区分大小写),返回 bool 值true 为取消绑定成功")
@RequestMapping(value = "withdrawThirdPartyBings", method = {RequestMethod.POST}, consumes = {CONTENT_TYPE_FORMED})
@ResponseBody
public CommonReturnType unbindThirdPartAccount(@RequestParam(value = "token", required = true) String token,
@RequestParam(value = "platform", required = true) String platform) throws BusinessException {
if(platform == null || platform.isEmpty()){
throw new BusinessException(BusinessErrorCode.PARAMETER_VALIDATION_ERROR, "参数错误,第三方平台不能为空");
}
Boolean isSuccess = thirdPartyUserService.unbindThirdPartAccount(token, platform);
if(!isSuccess){
throw new BusinessException(BusinessErrorCode.THIRD_PARTY_UNBIND_FAIL, "取消绑定失败,系统错误");
}
return CommonReturnType.create("success");
}
// 创建授权request
private AuthRequest getAuthRequest(String platform) throws BusinessException {
switch (platform.toLowerCase()) {
case "gitee":
return new AuthGiteeRequest(AuthConfig.builder()
.clientId(thirdPartyConfig.getGiteeClientId())
.clientSecret(thirdPartyConfig.getGiteeClientsecret())
.redirectUri(thirdPartyConfig.getGiteeRedirecturi())
.build());
case "oschina":
return new AuthOschinaRequest(AuthConfig.builder()
.clientId(thirdPartyConfig.getOschinaClientId())
.clientSecret(thirdPartyConfig.getOschinaClientsecret())
.redirectUri(thirdPartyConfig.getOschinaRedirecturi())
.build());
case "feishu":
return new AuthFeishuRequest(AuthConfig.builder()
.clientId(thirdPartyConfig.getFeishuClientId())
.clientSecret(thirdPartyConfig.getFeishuClientsecret())
.redirectUri(thirdPartyConfig.getFeishuRedirecturi())
.build());
case "github":
return new AuthGithubRequest(AuthConfig.builder()
.clientId(thirdPartyConfig.getGithubClientid())
.clientSecret(thirdPartyConfig.getGithubClientsecret())
.redirectUri(thirdPartyConfig.getGithubRedirecturi())
.build());
case "qq":
return new AuthQqRequest(AuthConfig.builder()
.clientId(thirdPartyConfig.getQqClientid())
.clientSecret(thirdPartyConfig.getQqClientsecret())
.redirectUri(thirdPartyConfig.getQqRedirecturi())
.build());
default:
throw new BusinessException(BusinessErrorCode.PARAMETER_VALIDATION_ERROR, "不支持该第三方平台");
}
}
}