集成谷歌登录

配置项目的注意点
  • 在集成登录时,需要在谷歌的云平台创建一个项目,在此项目中配置下redirect_uri、权限等信息。
  • 创建完项目后,将client_id和client_secret保存下来,后面集成时需要使用。
集成谷歌登录的时序图

在这里插入图片描述

流程关键点解释
  1. 在需要集成谷歌登录的系统的登录页面添加一个谷歌登录按钮,点击此按钮跳转到https://accounts.google.com/o/oauth2/v2/auth?client_id=123456-sskjaksj2332jkdjkds99339wowiei.apps.googleusercontent.com&redirect_uri=https://localhost:8080/page/main&scope=openid%20profile%20email&response_type=code这个地址,这个地址会进入谷歌的登录页面。

  2. 当用户输入完谷歌账号和密码,登录完成后,谷歌会重定向到我们提供给谷歌的重定向地址,这里给个我重定向后的地址示例https://localhost:8080/page/main?code=4%2F0AfJohXksR-Dkt_uO0Sg2ThXm-VMlXTN_9Yp4XzZQa5FvpeMUesvFYiB1e8-35ocews2riQ&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&authuser=0&prompt=consent 在重定向页面可以拿到code,我们就可以拿着这个code传给后端的接口。

  3. 当后端拿到前端传过来的code后,需要先调用接口获取到accessToken,再拿着accessToken去请求接口获取用户信息

    • 获取accessToken的接口地址是https://oauth2.googleapis.com/token,POST请求,使用RestTemplate请求的示例代码如下;官方接口介绍

      /**
           * 获取accessToken
           * 接口官方地址:https://developers.google.com/identity/openid-connect/openid-connect?hl=zh-cn#discovery
           *
           * @param certificate
           * @param oauthClientDetails
           * @return
           */
          private AccessTokenResult accessToken(Certificate certificate, OauthClientDetails oauthClientDetails) {
              Map<String, String> uriVariables = new HashMap<>(5);
              uriVariables.put("redirect_uri", certificate.getRedirectUri());
              uriVariables.put("code", certificate.getCode());
              uriVariables.put("client_id", oauthClientDetails.getClientId());
              uriVariables.put("client_secret", oauthClientDetails.getClientSecret());
              uriVariables.put("grant_type", "authorization_code");
      
              String data = toUrlData(uriVariables);
              HttpHeaders headers = new HttpHeaders();
              headers.add("Content-Type", "application/x-www-form-urlencoded");
              HttpEntity<String> httpEntity = new HttpEntity<>(data, headers);
      
              AccessTokenResult accessTokenResult = restTemplate.postForObject(ACCESS_TOKEN_URL, httpEntity, AccessTokenResult.class);
              log.info("获取到Google的token为{}", accessTokenResult);
              if (accessTokenResult == null || StringUtils.isBlank(accessTokenResult.getAccessToken())) {
                  log.error("Google授权登陆失败,无法通过授权码获取信息 {}", accessTokenResult);
                  throw new BusinessException(ResultCodeEnum.OAUTH_REQ_ERROR);
              }
              return accessTokenResult;
          }
      
      private String toUrlData(Map<String, String> params) {
          StringJoiner data = new StringJoiner("&");
          Iterator<Map.Entry<String, String>> it = params.entrySet().iterator();
          while (it.hasNext()) {
              Map.Entry<String, String> next = it.next();
              data.add(next.getKey() + "=" + next.getValue());
          }
          return data.toString();
      }
      
      
      @Data
      @ToString
      public static class AccessTokenResult {
      
          @JsonAlias("access_token")
          private String accessToken;
      
          @JsonAlias("id_token")
          private String idToken;
      
          @JsonAlias("error")
          private String error;
      
          @JsonAlias("error_description")
          private String errorDescription;
      }
      
    • 获取用户信息的接口地址是https://www.googleapis.com/oauth2/v3/userinfo,GET请求,使用RestTemplate请求的示例代码如下;官方接口介绍

      /**
           * 获取用户信息
           *
           * @param accessToken
           * @return
           */
      private InnerUserInfo innerUserInfo(String accessToken) {
          String authorization = "Bearer " + accessToken;
          HttpHeaders headers = new HttpHeaders();
          headers.add("Authorization", authorization);
          HttpEntity<String> requestEntity = new HttpEntity<>(null, headers);
          InnerUserInfo innerUserInfo = restTemplate.exchange(USER_INFO_URL, requestEntity, InnerUserInfo.class);
          log.info("获取到Google的用户信息为{}", innerUserInfo);
          if (innerUserInfo == null) {
              log.warn("Google 无法获取用户信息");
              innerUserInfo = new InnerUserInfo();
          }
          if (StringUtils.isBlank(innerUserInfo.getName())) {
              log.warn("Google 无法获取用户信息 {}", innerUserInfo);
          }
          return innerUserInfo;
      }
      
      /**
           * 返回结果示例:
           * HTTP/1.1 200 OK
           * Content-Type: application/json
           * <p>
           * {
           * "sub": "248289761001",
           * "name": "Jane Doe",
           * "given_name": "Jane",
           * "family_name": "Doe",
           * "preferred_username": "j.doe",
           * "email": "janedoe@example.com",
           * "picture": "http://example.com/janedoe/me.jpg"
           * }
           * 官方地址:https://openid.net/specs/openid-connect-core-1_0.html#UserInfoResponse
           */
          @Data
          @ToString
          public static class InnerUserInfo {
      
              @JsonAlias("sub")
              private String sub;
      
              @JsonAlias("name")
              private String name;
      
              @JsonAlias("given_name")
              private String givenName;
      
              @JsonAlias("family_name")
              private String familyName;
      
              @JsonAlias("preferred_username")
              private String preferredUsername;
      
              @JsonAlias("email")
              private String email;
      
              @JsonAlias("picture")
              private String picture;
      
          }
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值