如何在我的 Angular 应用程序中获取 Google Oauth 2.0 的刷新令牌?
How do I get refresh token for Google Oauth 2.0 in my Angular Application?
我已经找到了一种使用 ng-gapi 生成访问令牌的方法,但是有什么方法可以获得刷新令牌,因为访问令牌的有效期只有一个小时。
您找到解决此问题的方法了吗?
我有类似的问题。根据参数中带有授权码的 Using OAuth 2.0 for Web Server Applications (Step 5) article, we can get a refresh token from the response of the request to https://oauth2.googleapis.com/token 端点。这个授权码是我使用 GoogleAuth 对象的 grantOfflineAccess() 方法获得的,returns 是对这个代码的承诺。我不确定这个解决方案是否足够正确,但对我来说效果很好。这里有一些方法,希望对你也有帮助。
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'
});
}
我已经找到了一种使用 ng-gapi 生成访问令牌的方法,但是有什么方法可以获得刷新令牌,因为访问令牌的有效期只有一个小时。
您找到解决此问题的方法了吗? 我有类似的问题。根据参数中带有授权码的 Using OAuth 2.0 for Web Server Applications (Step 5) article, we can get a refresh token from the response of the request to https://oauth2.googleapis.com/token 端点。这个授权码是我使用 GoogleAuth 对象的 grantOfflineAccess() 方法获得的,returns 是对这个代码的承诺。我不确定这个解决方案是否足够正确,但对我来说效果很好。这里有一些方法,希望对你也有帮助。
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'
});
}