Как получить токен ref sh для Google Oauth 2.0 в моем приложении Angular? - PullRequest
0 голосов
/ 10 февраля 2020

Я уже нашел способ генерирования токена доступа с помощью ng-gapi, но есть ли способ получить токен refre sh, так как токен доступа действителен только в течение одного часа.

1 Ответ

2 голосов
/ 18 марта 2020

Нашли решение для этой проблемы? Я был снабжен аналогичной проблемой. Согласно статье Использование OAuth 2.0 для приложений веб-сервера (шаг 5) , мы можем получить токен refre sh из ответа на запрос https://oauth2.googleapis.com/token конечная точка с кодом авторизации в параметрах. Этот код авторизации я получил, используя grantOfflineAccess () метод объекта GoogleAuth, который возвращает обещание с этим кодом. Я не уверен, что это решение достаточно правильно, но оно прекрасно работает для меня. Вот некоторые методы, я надеюсь, это вам тоже поможет.

private tokenRequestParams: TokenReqParams = {
    client_id: AuthService.CLIENT_ID_KEY,
    client_secret: AuthService.CLIENT_SECRET_KEY,
    redirect_uri: 'http://localhost:4200',
    grant_type: 'authorization_code'
  };

  /**
   * if a user was logged the method returns user info, if not - checks that if refresh token   has been stored
   * and accordingly to this uses different methods for user sing-in
   * @returns - the data of the authorized user
   */
  public login(): Observable<User> {
    const isUserLoggedIn = this.refreshToken && this.accessToken;
    if (isUserLoggedIn) {
      return this.getUserInfo();
    } else {
      return this.googleAuthService.getAuth().pipe(
        switchMap( auth => {
          return (!this.refreshToken) ? this.firstSignIn(auth) : this.signIn(auth);
        })
      );
    }
  }
  
  
    /**
   * The method makes sign-in action and return's data of the user who was authorized
   * method will be used when grants were allowed after first sign in
   * @params auth - GoogleAuth object
   * @returns - user data
   */
  private firstSignIn(auth: GoogleAuth): Observable<User> {
    return from(auth.grantOfflineAccess()).pipe(
      switchMap(code => this.fetchToken({code: code.code}).pipe(
        map(() => this.signInSuccessHandler(auth.currentUser.get()))
      ))
    );
  }
  
  
    /**
   * The method makes sign-in action and return's data of the user who was authorized
   * method will be used when grants were allowed after first sign in
   * @params auth - GoogleAuth object
   * @returns - user data
   */
  private signIn(auth: GoogleAuth): Observable<User> {
    return from(
      auth.signIn().then(
        (res: GoogleUser) => this.signInSuccessHandler(res),
        err => { throw Error(err); }
      )).pipe(
      map((user: User) => user),
      catchError(() => throwError('login failed'))
    );
  }


  /**
   * The method fetches access token or both tokens (access and refresh) depending of received options
   * and stores them to local and session storage's
   * @params params - object, that determine which grant of token gets
   * details: https://developers.google.com/identity/protocols/oauth2/web-server#creatingclient
   * @returns - object with token data
   */
  private fetchToken(params: TokenAccessParams | TokenRefreshParams): Observable<Token> {
    const requestParams = {
      ...this.tokenRequestParams,
      ...params
    };
    return this.httpClient.post(this.TOKEN_ENDPOINT, requestParams).pipe(
      tap((res: Token) => {
        const {access_token, refresh_token} = res;
        sessionStorage.setItem(AuthService.SESSION_ST_ACCESS_TOKEN, access_token);
        if (refresh_token) { localStorage.setItem(AuthService.LOCAL_ST_REFRESH_TOKEN, refresh_token); }
      })
    );
  }


  /**
   * Method use current token to get new token
   * @returns - New token
   */
  private updateAccessToken(): Observable<any> {
    return this.fetchToken({
      refresh_token: this.refreshToken,
      grant_type: 'refresh_token'
    });
  }
...