更换谷歌登录token解析方式
This commit is contained in:
@@ -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")); // 排除登录接口
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,4 +34,6 @@ public interface LoginService extends IService<User> {
|
||||
User getUserInfo();
|
||||
|
||||
LoginVO parseGoogleCredential(String credential) throws ParseException, JOSEException, IOException;
|
||||
|
||||
LoginVO parseGoogleAccessToken(String accessToken);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user