我正在尝试为我的网站实现google身份验证,它是React前端和Spring Boot REST后端。
对于我的 React 应用程序,我找到了一个提供 Google 登录按钮的库,在其中我可以指定我的应用程序的“客户端 ID”,在 Google 开发者控制台中注册以及其余部分(将用户重定向到 google 身份验证页面, 访问令牌/ID令牌)的检索是由该库完成的。
现在我想将此访问令牌发送到我的后端,用它向谷歌发出请求,以验证该前端用户是否是真正的谷歌用户,谁正确地进行了身份验证并通过显示此访问来获取该用户的数据谷歌令牌(我只想要电子邮件/姓名/子,这是用户唯一的谷歌ID)。我是否正在寻找一些库来将此谷歌访问令牌交换为用户数据?
我也对以下事实感到困惑:所有 oauth 教程都说,当用户在 google 页面上进行身份验证时,我的应用程序将收到一个 授权代码 ,但正如我所说,我的前端收到访问令牌和 id 令牌。是因为我正在使用的库吗? https://www.npmjs.com/package/react-google-login这是库
这是当用户在谷歌页面上进行身份验证时到达我的客户端应用程序的数据
谢谢
我也遇到了和你一样的问题。我通过使用谷歌的GoogleIdTokenVerifier解决了这个问题。设置非常简单。
这是我的代码:
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.gson.GsonFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Collections;
@RestController
@RequestMapping(value = "/api/authenticate")
public final class AuthenticationController {
@GetMapping
public String exchange(@Autowired NetHttpTransport transport, @Autowired GsonFactory factory, HttpServletRequest request) throws GeneralSecurityException, IOException, IllegalAccessException {
// get id_token from Authorization Bearer
String token = this.getTokenFromRequest(request);
// Create verifier
GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, factory)
.setAudience(Collections.singletonList(<CLIENT_ID_HERE>))
.build();
// Verify it
GoogleIdToken idToken = verifier.verify(token);
if (idToken == null) {
throw new IllegalAccessException("Invalid id_token");
}
// Access payload
System.out.println("Email: " + idToken.getPayload().getEmail());
}
public String getTokenFromRequest(HttpServletRequest request) throws IllegalAccessException {
String token = request.getHeader("Authorization");
String[] parts = token.split(" ");
if (parts.length != 2 || !parts[0].contains("Bearer")) {
throw new IllegalAccessException("Authorization Bearer format invalid. <Bearer {token}>");
}
return parts[1];
}
}
Maven 依赖项:
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>1.30.4</version>
</dependency>
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client-gson</artifactId>
<version>1.21.0</version>
</dependency>
也许我迟到了,但让我把它留在这里:
这可能是一种可能的控制器方法,用于将代码交换为令牌。
@PostMapping("/check/code/google")
public ResponseEntity<?> handleGoogleAuthCode(@RequestBody Map<String, String> codeMap) {
String code = codeMap.get("code");
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
Map<String, String> params = new HashMap<>();
params.put("code", code);
params.put("client_id", clientId);
params.put("client_secret", clientSecret);
String redirectUri = "https://bpnckmnjnpoohfnodnhjpehocneckmmc.chromiumapp.org/";
params.put("redirect_uri", redirectUri);
params.put("grant_type", "authorization_code");
HttpEntity<Map<String, String>> request = new HttpEntity<>(params, headers);
ResponseEntity<Map> response = restTemplate.postForEntity("https://oauth2.googleapis.com/token", request, Map.class);
Map<String, Object> responseBody = response.getBody();
String accessToken = (String) responseBody.get("access_token");
// Use the access token to authenticate the user
// Your logic here to associate the user with the access token
// Set the authentication in the SecurityContext
// Authentication auth = Create your own authentication object based on the user's details
// SecurityContextHolder.getContext().setAuthentication(auth);
return ResponseEntity.ok().build();
}