更换谷歌登录token解析方式

This commit is contained in:
2025-11-06 14:36:47 +08:00
parent 8f0f0c7a0d
commit 34f666719a
6 changed files with 90 additions and 6 deletions

View File

@@ -40,7 +40,7 @@ public class WebConfig implements WebMvcConfigurer {
registry.addInterceptor(jwtInterceptor)
.addPathPatterns("/api/**/**") // 保护这些路径
.excludePathPatterns(Arrays.asList("/api/auth/precheckEmail", "/api/auth/registerOrLogin",
"/api/auth/forgotPwd", "/api/style/callback", "/api/auth/parseGoogleCredential")); // 排除登录接口
"/api/auth/forgotPwd", "/api/style/callback", "/api/auth/parseGoogleAccessToken")); // 排除登录接口
}
/**

View File

@@ -106,10 +106,19 @@ public class LoginController {
* 前端直接将credential传给服务端验证
* 服务端直接解析和验证JWT无需与Google服务器交换
*/
@CrossOrigin
@GetMapping("/parseGoogleCredential")
// @GetMapping("/parseGoogleCredential")
public ApiResponse<LoginVO> parseGoogleCredential(@RequestParam("credential") String credential) throws ParseException, IOException, JOSEException {
return ApiResponse.success(loginService.parseGoogleCredential(credential));
}
/**
* 使用OAuth 2.0方式登录
* @param accessToken 前端通过Google回调获取的token
* @return 用户登录信息
*/
@GetMapping("/parseGoogleAccessToken")
public ApiResponse<LoginVO> parseGoogleAccessToken(@RequestParam("accessToken") String accessToken) {
return ApiResponse.success(loginService.parseGoogleAccessToken(accessToken));
}
}

View File

@@ -34,4 +34,6 @@ public interface LoginService extends IService<User> {
User getUserInfo();
LoginVO parseGoogleCredential(String credential) throws ParseException, JOSEException, IOException;
LoginVO parseGoogleAccessToken(String accessToken);
}

View File

@@ -6,6 +6,7 @@ import com.aida.lanecarford.common.enums.LanguageEnum;
import com.aida.lanecarford.common.response.ResultEnum;
import com.aida.lanecarford.common.security.JwtUtil;
import com.aida.lanecarford.common.security.context.UserContext;
import com.aida.lanecarford.dto.GoogleUser;
import com.aida.lanecarford.dto.LoginRequest;
import com.aida.lanecarford.entity.User;
import com.aida.lanecarford.exception.BusinessException;
@@ -16,9 +17,11 @@ import com.aida.lanecarford.util.RandomsUtil;
import com.aida.lanecarford.util.SendEmailUtil;
import com.aida.lanecarford.vo.AuthPrincipalVO;
import com.aida.lanecarford.vo.LoginVO;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.crypto.RSASSAVerifier;
import com.nimbusds.jose.jwk.JWK;
@@ -30,12 +33,13 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.io.IOException;
import java.net.URL;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.util.Objects;
import java.util.*;
import static com.aida.lanecarford.common.enums.AuthenticationOperationTypeEnum.*;
@@ -58,6 +62,8 @@ public class LoginServiceImpl extends ServiceImpl<UserMapper, User> implements L
private String googleClientId;
@Value("${google.client_secret}")
private String googleClientSecret;
@Value("${google.redirect_uri}")
private String googleRedirectUri;
@Override
@@ -316,7 +322,72 @@ public class LoginServiceImpl extends ServiceImpl<UserMapper, User> implements L
};
}
@Override
public LoginVO parseGoogleAccessToken(String accessToken) {
try {
log.info("accessToken: {}", accessToken);
// 使用 accessToken 获取 Google 用户信息
// GoogleUser googleUser = getGoogleUserFromCode(accessToken);
GoogleUser googleUser = getGoogleUserInfo(accessToken);
log.info("googleUser: {}", JSON.toJSONString(googleUser));
// 1. 根据用户邮箱查询是登录还是注册
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(User::getEmail, googleUser.getEmail());
User user = getOne(queryWrapper);
AuthenticationOperationTypeEnum type = Objects.isNull(user) ? REGISTER: LOGIN;
LoginRequest loginRequest = new LoginRequest();
loginRequest.setName(googleUser.getName());
loginRequest.setEmail(googleUser.getEmail());
loginRequest.setOperationType(type.name());
return switch (type) {
case REGISTER -> register(loginRequest);
case LOGIN -> login(loginRequest);
default -> throw new BusinessException("Unknown authentication operation type.");
};
} catch (Exception e) {
throw new BusinessException("Error processing Google login: " + e.getMessage());
}
}
private static final String TOKEN_URL = "https://oauth2.googleapis.com/token";
public GoogleUser getGoogleUserFromCode(String code) {
// Step 1: Exchange code for access_token
String accessToken = getAccessToken(code);
log.info("accessToken" + accessToken);
// Step 2: Use access_token to get Google User info
return getGoogleUserInfo(accessToken);
}
private String getAccessToken(String code) {
RestTemplate restTemplate = new RestTemplate();
Map<String, String> params = new HashMap<>();
params.put("client_id", googleClientId);
params.put("client_secret", googleClientSecret);
params.put("redirect_uri", googleRedirectUri);
params.put("grant_type", "authorization_code");
params.put("code", code);
// 使用 RestTemplate 发起请求以获取 access_token
GoogleTokenResponse response = restTemplate.postForObject(TOKEN_URL, params, GoogleTokenResponse.class);
return response.getAccessToken();
}
private static final String USER_INFO_URL = "https://www.googleapis.com/oauth2/v3/userinfo";
private GoogleUser getGoogleUserInfo(String accessToken) {
/*System.setProperty("http.proxyHost", "127.0.0.1");
System.setProperty("http.proxyPort", "7890");
System.setProperty("https.proxyHost", "127.0.0.1");
System.setProperty("https.proxyPort", "7890");*/
RestTemplate restTemplate = new RestTemplate();
String url = USER_INFO_URL + "?access_token=" + accessToken;
return restTemplate.getForObject(url, GoogleUser.class);
}
}

View File

@@ -91,4 +91,5 @@ webhook:
google:
client_id: 216037134725-7q8vqp0ohtmohlosltkfg7bd2v29rm5a.apps.googleusercontent.com
client_secret: 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
client_secret: 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
redirect_uri: ${webhook.domain}/api/auth/google_callback

View File

@@ -91,4 +91,5 @@ webhook:
google:
client_id: 216037134725-7q8vqp0ohtmohlosltkfg7bd2v29rm5a.apps.googleusercontent.com
client_secret: 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
client_secret: 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
redirect_uri: ${webhook.domain}/api/auth/google_callback