我在应用程序中使用基于令牌的身份验证。我的后端是使用Restful Service(Spring)开发的。后端代码非常好生成所需的访问令牌和使用时间表的刷新令牌,因此我已经超过了HTTP类,并具有以下方式:
export class customHttp extends Http {
headers: Headers = new Headers({ 'Something': 'Something' });
options1: RequestOptions = new RequestOptions({ headers: this.headers });
private refreshTokenUrl = AppSettings.REFRESH_TOKEN_URL;
constructor(backend: ConnectionBackend,
defaultOptions: RequestOptions,private refresh:OauthTokenService) {
super(backend, defaultOptions);
}
request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
console.log("custom http ");
return super.request(url, options)
.catch((err) => {
if (err.status === 401) {
console.log(" custome http 401 ");
// refresh the token
this.refresh.refresh().subscribe((tokenObj)=>{
console.log("tokenobj ");
})
} else {
console.log("err " + err);
}
}); } }
当我遇到循环依赖性错误时,我会陷入刷新令牌()方法,因此我尝试在另一个模块中使用刷新服务,但没有运气。我使用的方法与此处理刷新代币中提到的方法相同,任何帮助都很好!
这对我有用:
request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
//adding access token to each http request before calling super(..,..)
let token = this.authenticationService.token;
if (typeof url === 'string') {
if (!options) {
options = { headers: new Headers() };
}
options.headers.set('Authorization', `Bearer ${token}`);
}
else {
url.headers.set('Authorization', `Bearer ${token}`);
}
return super.request(url, options)
.catch((error) => {
//if got authorization error - try to update access token
if (error.status = 401) {
return this.authenticationService.updateToken()
.flatMap((result: boolean) => {
//if got new access token - retry request
if (result) {
return this.request(url, options);
}
//otherwise - throw error
else {
return Observable.throw(new Error('Can't refresh the token'));
}
})
}
else {
Observable.throw(error);
}
})
}
更新:AuthenTicationservice.updateToken()实现应取决于您使用的授权提供商/授权机制。就我而言,它是Oauth Athorization服务器,因此实现基本上是在主体中使用Refresh令牌发送发布请求,以配置令牌URL并返回更新的访问和刷新令牌。TokenendPointUrl由OAuth配置,并且问题访问和刷新令牌(取决于已发送的Grant_Type)。因为我需要刷新令牌,所以我将Grant_Type设置为refresh_token。代码看起来与以下方式相似:
updateToken(): Observable<boolean> {
let body: string = 'refresh_token=' + this.refreshToken + '&grant_type=refresh_token';
return this.http.post(tokenEndPointUrl, body, this.options)
.map((response: Response) => {
var returnedBody: any = response.json();
if (typeof returnedBody.access_token !== 'undefined'){
localStorage.setItem(this.tokenKey, returnedBody.access_token);
localStorage.setItem(this.refreshTokenKey, returnedBody.refresh_token);
return true;
}
else {
return false;
}
})
}
希望它有帮助
对于那些进入此页面而不了解它的人的人。
易于理解:
创建您的刷新令牌方法: //以某种方式检索刷新令牌
refreshToken(){
let refreshToken = sessionStorage.getItem('refresh_token');
let body = 'grant_type=refresh_token&refresh_token=' + refreshToken;
var headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
headers.append('Authorization','Basic ' + btoa('something:something'));
return this.http.post('your auth url',body,{headers: headers})
}
比您的http请求中的
testService(){
this.authHttp.get('your secured service url')
.map(res => {
return res;
})
.catch(error=> {
if (error.status === 401) {
return this.refreshToken().flatMap((newToken) => {
let newAccessToken = newToken.json();
sessionStorage.setItem('id_token', newAccessToken['access_token']);
sessionStorage.setItem('refresh_token', newAccessToken['refresh_token']);
return this.authHttp.request('your secured service url');
})
} else {
return Observable.throw(error);
}
})
.subscribe(res => console.log(res));
}
不要忘记导入您需要的内容:
import { AuthHttp } from 'angular2-jwt';
import { Observable } from "rxjs/Observable";
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
请勿订阅您的刷新令牌方法。如果您这样做,您将在服务调用方法的平面图中看到一个大错误。
感谢您回复@dragonfly,这对我有用
post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
//check if the token is expired then set the latest token
if (this.isTokenExpired) {
options.headers.set('Authorization', 'Bearer ' + localStorage.getItem("accessToken"));
}
return super.post(url, body, options)
.catch((err) => {
//if authentication error
if (err.status === 401) {
this.isTokenExpired = true;
options.headers.set('Authorization', 'Bearer ' + localStorage.getItem("accessToken"));
//refresh the token
let refreshUrl = this.refreshTokenUrl;
//pass the refresh token
refreshUrl = refreshUrl.replace(':refreshToken', localStorage.getItem("refreshToken"));
//rest the access token
return super.get(refreshUrl).mergeMap((tokenObj) => {
localStorage.setItem("accessToken", tokenObj.json().value);
// reset the headers
options.headers.set('Authorization', 'Bearer ' + localStorage.getItem("accessToken"));
//retry the request with the new access token
return this.post(url, body, options)
})
.catch((refreshErr) => {
if (refreshErr.status == 400) {
console.log("refesh err");
window.location.href = 'request=logout';
}
return Observable.throw(refreshErr);
})
} else {
return err;
}
})
}
您能说出如何更新令牌(this.authenticationservice.updatetoken())?