使用JustAuth实现gittee登录
登录流程:
- 点击 Github 图标时,调用 handleGiteeLogin
- 获取 Gitee 登录地址并跳转
- Gitee 授权后,后端进行相关的验证登录等
- 成功后回调到gitee填的回调地址
1.添加依赖
<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
<version>1.16.5</version>
/dependency>
2.在 Gitee 创建应用获取必要的参数:
登录 Gitee
进入设置 -> 第三方应用
创建应用,获取 Client ID 和 Client Secret
设置回调地址,如: http://localhost:8080/oauth/gitee/callback
3.创建配置类
@Configuration
@ConfigurationProperties(prefix = "gitee")
@Data
public class JustAuthConfig {
private String clientId;
private String clientSecret;
private String redirectUri;
@Bean("giteeAuthRequest") // 指定 Bean 名称
public AuthGiteeRequest authGiteeRequest() {
return new AuthGiteeRequest(AuthConfig.builder()
.clientId(clientId)
.clientSecret(clientSecret)
.redirectUri(redirectUri)
.build());
}
}
4.在 application.yml 中配置参数
gitee:
client-id: 你的ClientID
client-secret: 你的ClientSecret
redirect-uri: 回调地址
5.登录控制器
package com.qiheyehua.qiheyuehuajavaee.controller;
import com.qiheyehua.qiheyuehuajavaee.Service.UserService;
import com.qiheyehua.qiheyuehuajavaee.domain.entity.User;
import com.qiheyehua.qiheyuehuajavaee.domain.vo.UserVO;
import com.qiheyehua.qiheyuehuajavaee.utils.JwtUtil;
import com.qiheyehua.qiheyuehuajavaee.utils.Result;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthGiteeRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RequestMapping("/oauth")
@RestController
@RequiredArgsConstructor
@Slf4j
public class OauthController {
@Qualifier("giteeAuthRequest") // 指定要注入的 Bean 名称
@Autowired
private AuthGiteeRequest authGiteeRequest;
@Autowired
private UserService userService;
@Autowired
private JwtUtil jwtUtil;
@GetMapping("/gitee/render")
public Result<String> renderAuth() {
String state = AuthStateUtils.createState();
String authorizeUrl = authGiteeRequest.authorize(state);
return Result.success(authorizeUrl);
}
@GetMapping("/gitee/callback")
public Result<Object> login(AuthCallback callback) {
try {
// 1. 获取 Gitee 用户信息
AuthResponse<AuthUser> response = authGiteeRequest.login(callback);
AuthUser authUser = response.getData();
// 2. 检查用户是否存在,不存在则创建
User user = userService.getByGiteeId(authUser.getUuid());
if (user == null) {
// 创建新用户
user = new User();
user.setGiteeId(authUser.getUuid());
user.setAvatar(authUser.getAvatar());
user.setUsername(authUser.getUsername());
user.setPhone(authUser.getNickname());
// 保存用户并获取生成的 ID
boolean save = userService.save(user);
if (!save) {
throw new RuntimeException("创建用户失败");
}
} else {
// 如果用户存在,更新用户信息
user.setAvatar(authUser.getAvatar());
user.setUsername(authUser.getUsername());
user.setPhone(authUser.getNickname());
boolean updated = userService.updateById(user);
if (!updated) {
throw new RuntimeException("更新用户信息失败");
}
}
// 3. 生成 token
String token = jwtUtil.generateToken(user.getUserId().intValue(), user.getUsername());
// 4. 构建返回结果
Map<String, Object> result = new HashMap<>(3);
result.put("token", token);
result.put("userInfo", UserVO.builder()
.userId(user.getUserId())
.username(user.getUsername())
.avatar(user.getAvatar())
.phone(user.getPhone())
.build());
return Result.success(result);
} catch (AuthException e) {
log.error("Gitee登录失败", e);
return Result.error(e.getMessage());
}
}
}
6.前端页面
前端页面,主要是实现点击gitee图标从后端得到连接跳转授权
<!-- 社交登录按钮 -->
<div class="flex justify-center space-x-4">
<button
type="button"
class="p-2 rounded-full bg-white/10 hover:bg-white/20 transition-colors flex items-center space-x-2"
@click="handleGiteeLogin"
>
<svg viewBox="0 0 1024 1024" class="w-6 h-6 text-white">
<path
fill="currentColor"
d="M512 1024C229.222 1024 0 794.778 0 512S229.222 0 512 0s512 229.222 512 512-229.222 512-512 512z m259.149-568.883h-290.74a25.293 25.293 0 0 0-25.292 25.293l-0.026 63.206c0 13.952 11.315 25.293 25.267 25.293h177.024c13.978 0 25.293 11.315 25.293 25.267v12.646a75.853 75.853 0 0 1-75.853 75.853h-240.23a25.293 25.293 0 0 1-25.267-25.293V417.203a75.853 75.853 0 0 1 75.827-75.853h353.946a25.293 25.293 0 0 0 25.267-25.292l0.077-63.207a25.293 25.293 0 0 0-25.268-25.293H417.152a189.62 189.62 0 0 0-189.62 189.645V771.15c0 13.977 11.316 25.293 25.294 25.293h372.94a170.65 170.65 0 0 0 170.65-170.65V480.384a25.293 25.293 0 0 0-25.293-25.267z"
></path>
</svg>
<span class="text-white text-sm">Gitee 登录</span>
</button>
</div>
js代码
// Gitee 登录处理
const handleGiteeLogin = async () => {
try {
const res = await getGiteeLoginUrl()
if (res.code === 200) {
// 使用 window.location.href 进行跳转,这样会刷新页面
window.location.href = res.data
}
} catch (error) {
console.error('获取 Gitee 登录地址失败:', error)
ElMessage.error('获取 Gitee 登录地址失败')
}
}
封装的请求
// 获取 Gitee 登录地址
export function getGiteeLoginUrl() {
return request({
url: '/oauth/gitee/render',
method: 'get'
})
}