Spring Exchange用户信息的Google访问令牌

68bkxrlz  于 2024-01-05  发布在  Spring
关注(0)|答案(2)|浏览(141)

我正在尝试为我的网站实现Google身份验证,它是React前端和Sping Boot REST后端。
对于我的React应用程序,我找到了一个提供Google Login按钮的库,我可以在其中指定我的应用程序的“client-id”,在Google开发人员的控制台中注册,其余的(将用户重定向到Google身份验证页面,检索访问令牌/ID令牌)由这个库完成。
现在我想把这个访问令牌发送到我的后端,用它来向谷歌发出请求,以验证这个前端用户是一个真实的谷歌用户,谁正确认证,并通过显示这个访问令牌谷歌获得这个用户的数据(我只想要电子邮件/名称/子,这是用户唯一的谷歌ID).我正在寻找一些库来交换这个谷歌访问令牌的用户数据?
我也很困惑,所有的oauth教程都说,当用户在google页面上进行身份验证时,我的应用程序将收到一个授权码,但我的前端收到的是acces token和id token。这是因为我使用的库吗?https://www.npmjs.com/package/react-google-login这是库
这是当用户在Google页面console.log(response) in browser上进行身份验证时,进入我的客户端应用程序的数据
谢谢

sh7euo9m

sh7euo9m1#

我和你有同样的问题。我通过使用谷歌的GoogleIdTokenVerifier解决了它。设置非常简单。
这是我的代码:

  1. import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
  2. import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
  3. import com.google.api.client.http.javanet.NetHttpTransport;
  4. import com.google.api.client.json.gson.GsonFactory;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.web.bind.annotation.*;
  7. import javax.servlet.http.HttpServletRequest;
  8. import java.io.IOException;
  9. import java.security.GeneralSecurityException;
  10. import java.util.Collections;
  11. @RestController
  12. @RequestMapping(value = "/api/authenticate")
  13. public final class AuthenticationController {
  14. @GetMapping
  15. public String exchange(@Autowired NetHttpTransport transport, @Autowired GsonFactory factory, HttpServletRequest request) throws GeneralSecurityException, IOException, IllegalAccessException {
  16. // get id_token from Authorization Bearer
  17. String token = this.getTokenFromRequest(request);
  18. // Create verifier
  19. GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, factory)
  20. .setAudience(Collections.singletonList(<CLIENT_ID_HERE>))
  21. .build();
  22. // Verify it
  23. GoogleIdToken idToken = verifier.verify(token);
  24. if (idToken == null) {
  25. throw new IllegalAccessException("Invalid id_token");
  26. }
  27. // Access payload
  28. System.out.println("Email: " + idToken.getPayload().getEmail());
  29. }
  30. public String getTokenFromRequest(HttpServletRequest request) throws IllegalAccessException {
  31. String token = request.getHeader("Authorization");
  32. String[] parts = token.split(" ");
  33. if (parts.length != 2 || !parts[0].contains("Bearer")) {
  34. throw new IllegalAccessException("Authorization Bearer format invalid. <Bearer {token}>");
  35. }
  36. return parts[1];
  37. }
  38. }

字符串
Maven依赖项:

  1. <dependency>
  2. <groupId>com.google.api-client</groupId>
  3. <artifactId>google-api-client</artifactId>
  4. <version>1.30.4</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>com.google.http-client</groupId>
  8. <artifactId>google-http-client-gson</artifactId>
  9. <version>1.21.0</version>
  10. </dependency>

展开查看全部
6uxekuva

6uxekuva2#

也许我迟到了,但让我把它留在这里:
1.您正在使用的react库故意检索访问令牌,因为它假定您将使用它作为前端,因此使用此令牌,您可以向资源服务器发出任何进一步的请求。在这种情况下,资源服务器和auth服务器是相同的。例如,你想使用谷歌作为OAuth提供者,并在你的前端应用程序中显示谷歌的联系人。所以谷歌这里是认证服务器(react的lib使Google的API调用访问令牌)和资源服务器(使用访问令牌,您的react应用程序请求Google联系人)。
1.如果后台进入游戏,您需要获得一个授权码-一个临时代码,(不是前端;它是OAuth规范中的客户端)将交换访问令牌。React向auth服务器请求auth代码(Google/Facebook/Okta)将此代码发送到后端。后端将此代码沿着client_id,secret,grant_type.和OAuth规范中定义的其他参数发送到同一个OAuth服务器。Auth服务器比较所有参数,如果所有参数都正确,则返回令牌。后端接收令牌,因此我们可以声明我们将令牌交换为代码。下一步是将令牌发送回前端,将其存储在前端,并将其附加到后端的每个后续请求中。当然,我们还需要处理刷新令牌。
这可能是一个可能的控制器方法,用于将代码交换为令牌。

  1. @PostMapping("/check/code/google")
  2. public ResponseEntity<Striing> handleGoogleAuthCode(@RequestBody Map<String, String> codeMap) {
  3. String code = codeMap.get("code");
  4. RestTemplate restTemplate = new RestTemplate();
  5. HttpHeaders headers = new HttpHeaders();
  6. headers.setContentType(MediaType.APPLICATION_JSON);
  7. Map<String, String> params = new HashMap<>();
  8. params.put("code", code);
  9. params.put("client_id", clientId);
  10. params.put("client_secret", clientSecret);
  11. String redirectUri = "https://bpnckmnjnpoohfnodnhjpehocneckmmc.chromiumapp.org/";
  12. params.put("redirect_uri", redirectUri);
  13. params.put("grant_type", "authorization_code");
  14. HttpEntity<Map<String, String>> request = new HttpEntity<>(params, headers);
  15. ResponseEntity<Map> response = restTemplate.postForEntity("https://oauth2.googleapis.com/token", request, Map.class);
  16. Map<String, Object> responseBody = response.getBody();
  17. String accessToken = (String) responseBody.get("access_token");
  18. String email = profile.getEmailAddresses().get(0).getValue();
  19. String name = profile.getNames().get(0).getGivenName();
  20. try {
  21. // Create an Authentication Object
  22. SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ROLE_USER"); // "ROLE_" is a convention
  23. Authentication auth = new UsernamePasswordAuthenticationToken(email, null, Collections.singletonList(authority));
  24. // Set the Authentication Object in Security Context
  25. SecurityContextHolder.getContext().setAuthentication(auth);
  26. } catch (Exception e) {
  27. // Token is invalid
  28. SecurityContextHolder.clearContext();
  29. }
  30. JwtUtil bean = applicationContext.getBean(JwtUtil.class);
  31. String jwt = bean.generateSessionToken(email);
  32. return jwt;
  33. }

字符串

展开查看全部

相关问题