mirror of
https://gitee.com/bookshelfplus/bookshelfplus
synced 2025-09-22 01:30:40 +08:00
Gitee授权登录成功
This commit is contained in:
@@ -5,6 +5,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import plus.bookshelf.Common.Enum.plus.bookshelf.TencentCloud.COS.CosProperties;
|
||||
@@ -16,6 +17,7 @@ import plus.bookshelf.Common.TencentCloud.COS.GeneratePresignatureUrl;
|
||||
@SpringBootApplication(scanBasePackages = {"plus.bookshelf"})
|
||||
@RestController
|
||||
@MapperScan("plus.bookshelf.Dao.Mapper")
|
||||
// @EnableTransactionManagement // 引入事务管理
|
||||
public class App {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("Dreams remain daydreams until they are put into action. \n" +
|
||||
|
@@ -16,8 +16,8 @@ public enum BusinessErrorCode implements CommonError {
|
||||
OPERATION_NOT_ALLOWED(30001, "用户没有此操作的权限"),
|
||||
|
||||
// 40000开头为第三方登录相关错误定义
|
||||
THIRD_PARTY_LOGIN_FAIL(40001, "第三方登录失败");
|
||||
|
||||
THIRD_PARTY_LOGIN_FAIL(40001, "第三方登录失败"),
|
||||
THIRD_PARTY_ACCOUNT_ALREADY_BOUND(40002, "该账号已被其他账号绑定");
|
||||
|
||||
|
||||
private BusinessErrorCode(int errCode, String errMsg) {
|
||||
|
@@ -53,11 +53,11 @@ public class ThirdPartyController extends BaseController {
|
||||
return CommonReturnType.create(authorizeUrl);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "快捷登录回调函数", notes = "传入 code 值,进行登录")
|
||||
@ApiOperation(value = "快捷登录回调函数", notes = "如果传入 token 那么就是绑定第三方账号到当前登录账号,否则就是通过第三方授权登录")
|
||||
@RequestMapping(value = "callback/{platform}", method = {RequestMethod.GET})
|
||||
@ResponseBody
|
||||
public CommonReturnType callback(@PathVariable("platform") String platform,
|
||||
// @RequestParam Map<String,String> params,
|
||||
@RequestParam(value = "token", required = false) String token,
|
||||
AuthCallback callback) throws BusinessException {
|
||||
AuthRequest authRequest = getAuthRequest(platform);
|
||||
AuthResponse authResponse;
|
||||
@@ -67,15 +67,21 @@ public class ThirdPartyController extends BaseController {
|
||||
// [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);
|
||||
|
||||
UserModel userModel = thirdPartyUserService.loginCallback(authResponse);
|
||||
UserVO userVO = UserController.convertFromService(userModel);
|
||||
|
||||
if (userModel != null) {
|
||||
String token = onLogin(userModel);
|
||||
userVO.setToken(token); // token 仅在用户登录时传一次,后面获取用户状态接口中不重复返回 token 信息
|
||||
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);
|
||||
}
|
||||
return CommonReturnType.create(userVO);
|
||||
}
|
||||
|
||||
// 创建授权request
|
||||
|
@@ -55,10 +55,16 @@ public interface ThirdPartyUserDOMapper {
|
||||
int updateByPrimaryKey(ThirdPartyUserDO record);
|
||||
|
||||
/**
|
||||
* 通过 uuid + source 查询第三方登录的用户信息(limit 1)
|
||||
* 通过 uuid + source 查询第三方登录的用户信息
|
||||
* @param uuid
|
||||
* @param source
|
||||
* @return
|
||||
*/
|
||||
ThirdPartyUserDO selectByUuidAndSource(String uuid, String source);
|
||||
|
||||
/**
|
||||
* 获取上一步插入数据的主键id
|
||||
* @return
|
||||
*/
|
||||
Integer getLastInsertId();
|
||||
}
|
@@ -5,6 +5,7 @@ import me.zhyd.oauth.model.AuthResponse;
|
||||
import me.zhyd.oauth.model.AuthToken;
|
||||
import me.zhyd.oauth.model.AuthUser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import plus.bookshelf.Common.Error.BusinessErrorCode;
|
||||
@@ -15,8 +16,9 @@ import plus.bookshelf.Dao.Mapper.ThirdPartyUserAuthDOMapper;
|
||||
import plus.bookshelf.Dao.Mapper.ThirdPartyUserDOMapper;
|
||||
import plus.bookshelf.Service.Model.UserModel;
|
||||
import plus.bookshelf.Service.Service.ThirdPartyUserService;
|
||||
import plus.bookshelf.Service.Service.UserService;
|
||||
|
||||
import java.util.Map;
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@Service
|
||||
public class ThirdPartyUserServiceImpl implements ThirdPartyUserService {
|
||||
@@ -30,6 +32,16 @@ public class ThirdPartyUserServiceImpl implements ThirdPartyUserService {
|
||||
@Autowired
|
||||
UserServiceImpl userService;
|
||||
|
||||
@Autowired
|
||||
RedisTemplate redisTemplate;
|
||||
|
||||
/**
|
||||
* 第三方登录
|
||||
*
|
||||
* @param authResponse
|
||||
* @return
|
||||
* @throws BusinessException
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public UserModel loginCallback(AuthResponse authResponse) throws BusinessException {
|
||||
@@ -53,14 +65,16 @@ public class ThirdPartyUserServiceImpl implements ThirdPartyUserService {
|
||||
|
||||
if (existThirdPartyUserDO != null) {
|
||||
// 之前已经授权登录过
|
||||
// 更新数据库中的第三方登录信息
|
||||
currentThirdPartyUserDO.setId(existThirdPartyUserDO.getId());
|
||||
thirdPartyUserDOMapper.updateByPrimaryKeySelective(currentThirdPartyUserDO);
|
||||
|
||||
// 检查第三方账号有无绑定到系统账号
|
||||
ThirdPartyUserAuthDO thirdPartyUserAuthDO = thirdPartyUserAuthDOMapper.selectByThirdPartyUserId(currentThirdPartyUserDO.getId());
|
||||
ThirdPartyUserAuthDO thirdPartyUserAuthDO = thirdPartyUserAuthDOMapper.selectByThirdPartyUserId(existThirdPartyUserDO.getId());
|
||||
if (thirdPartyUserAuthDO != null) {
|
||||
// 已经绑定到系统账号
|
||||
|
||||
// 更新数据库中的第三方登录信息
|
||||
currentThirdPartyUserDO.setId(existThirdPartyUserDO.getId());
|
||||
thirdPartyUserDOMapper.updateByPrimaryKeySelective(currentThirdPartyUserDO);
|
||||
|
||||
// 取得用户信息,并登录
|
||||
Integer userId = thirdPartyUserAuthDO.getUserId();
|
||||
UserModel userModel = userService.getUserById(userId);
|
||||
@@ -71,8 +85,6 @@ public class ThirdPartyUserServiceImpl implements ThirdPartyUserService {
|
||||
}
|
||||
} else {
|
||||
// 之前未授权登录过
|
||||
// 将新的用户信息插入到数据库
|
||||
thirdPartyUserDOMapper.insertSelective(currentThirdPartyUserDO);
|
||||
throw new BusinessException(BusinessErrorCode.PARAMETER_VALIDATION_ERROR, "第三方登录失败,该第三方账号未绑定到系统账号,请先绑定");
|
||||
}
|
||||
} else {
|
||||
@@ -81,6 +93,70 @@ public class ThirdPartyUserServiceImpl implements ThirdPartyUserService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Boolean bindThirdPartAccountCallback(AuthResponse authResponse, String token) throws BusinessException {
|
||||
int code = authResponse.getCode();
|
||||
if (code == 5008) {
|
||||
// 第三方平台拒绝授权
|
||||
throw new BusinessException(BusinessErrorCode.PARAMETER_VALIDATION_ERROR, "绑定失败,用户已取消第三方授权或第三方平台拒绝授权");
|
||||
} else if (code == 5009) {
|
||||
// 授权过期
|
||||
throw new BusinessException(BusinessErrorCode.PARAMETER_VALIDATION_ERROR, "第三方授权过期,请尝试重新绑定");
|
||||
}
|
||||
if (code == 2000) {
|
||||
// 回调成功
|
||||
// 将回调结果转换为 Data Object
|
||||
ThirdPartyUserDO currentThirdPartyUserDO = getThirdPartyUserDOFromAuthData(authResponse.getData());
|
||||
|
||||
// 根据 uuid + source 唯一确定一个平台的用户 refer: https://justauth.wiki/features/integrate-existing-systems/
|
||||
String uuid = currentThirdPartyUserDO.getUuid();
|
||||
String source = currentThirdPartyUserDO.getSource();
|
||||
ThirdPartyUserDO existThirdPartyUserDO = thirdPartyUserDOMapper.selectByUuidAndSource(uuid, source);
|
||||
|
||||
if (existThirdPartyUserDO == null) {
|
||||
// 之前未授权过
|
||||
|
||||
// 获取当前登录用户信息
|
||||
UserModel userModel = userService.getUserByToken(redisTemplate, token);
|
||||
if (userModel == null) {
|
||||
throw new BusinessException(BusinessErrorCode.PARAMETER_VALIDATION_ERROR, "绑定失败,用户未登录");
|
||||
}
|
||||
|
||||
// 将用户账号与第三方账号信息插入到数据库
|
||||
int affectRows = thirdPartyUserDOMapper.insertSelective(currentThirdPartyUserDO);
|
||||
|
||||
// 判断是否插入成功
|
||||
if (affectRows > 0) {
|
||||
// 用户第三方账号保存到数据库表中的主键id
|
||||
Integer lastInsertId = thirdPartyUserDOMapper.getLastInsertId();
|
||||
|
||||
// 在 Auth 表中建立 用户 和第三方授权的联系
|
||||
ThirdPartyUserAuthDO thirdPartyUserAuthDO = new ThirdPartyUserAuthDO();
|
||||
thirdPartyUserAuthDO.setThirdPartyUserId(lastInsertId);
|
||||
thirdPartyUserAuthDO.setUserId(userModel.getId());
|
||||
int affectRows2 = thirdPartyUserAuthDOMapper.insert(thirdPartyUserAuthDO);
|
||||
// 判断是否插入成功
|
||||
if (affectRows2 > 0) {
|
||||
// 绑定成功
|
||||
return true;
|
||||
} else {
|
||||
throw new BusinessException(BusinessErrorCode.UNKNOWN_ERROR, "绑定失败,系统错误");
|
||||
}
|
||||
} else {
|
||||
// 第三方账号信息插入失败
|
||||
throw new BusinessException(BusinessErrorCode.UNKNOWN_ERROR, "绑定失败,系统错误");
|
||||
}
|
||||
} else {
|
||||
// 之前已经授权过
|
||||
throw new BusinessException(BusinessErrorCode.THIRD_PARTY_ACCOUNT_ALREADY_BOUND, "绑定失败,该账号已被其他账号绑定");
|
||||
}
|
||||
} else {
|
||||
// 未知错误
|
||||
throw new BusinessException(BusinessErrorCode.UNKNOWN_ERROR, "未知错误,绑定失败");
|
||||
}
|
||||
}
|
||||
|
||||
private ThirdPartyUserDO getThirdPartyUserDOFromAuthData(Object authData) {
|
||||
AuthUser data = (AuthUser) authData;
|
||||
String uuid = data.getUuid();
|
||||
|
@@ -15,4 +15,14 @@ public interface ThirdPartyUserService {
|
||||
*/
|
||||
@Transactional
|
||||
UserModel loginCallback(AuthResponse authResponse) throws BusinessException;
|
||||
|
||||
|
||||
/**
|
||||
* 个人账号中心绑定第三方账号回调函数
|
||||
* @param authResponse
|
||||
* @throws BusinessException
|
||||
* @return
|
||||
*/
|
||||
@Transactional
|
||||
Boolean bindThirdPartAccountCallback(AuthResponse authResponse, String token) throws BusinessException;
|
||||
}
|
||||
|
@@ -283,4 +283,7 @@
|
||||
from third_party_user_info
|
||||
where uuid = #{uuid} and `source` = #{source}
|
||||
</select>
|
||||
<select id="getLastInsertId" resultType="java.lang.Integer">
|
||||
SELECT LAST_INSERT_ID();
|
||||
</select>
|
||||
</mapper>
|
Reference in New Issue
Block a user