我已完成授权步骤,并通过 Laravel Passport 获取了访问 token 和刷新 token 。
我的 Angular 前端和 Laravel 后端工作正常。
我的主要问题是:
- 我应该如何以及何时使用刷新 token 来创建新的访问 token ?
- 这应该在后台完成还是用户必须单击按钮来刷新 token ?
- 创建新 token 时是否应该重新加载 Angular 页面?
最佳答案
我在我的 Angular 项目中使用 JWT 身份验证,其中 token 由 API 设置。
token 过期时我采取的方法如下所述 -
- 公开一个新的 API,它将获取过期的 token 并返回新创建的 token 。
- API 应在每次 REST API 调用中检查 token 过期情况。
- 如果 token 过期,API 应返回状态(根据标准,498 - 过期/无效)。
- 在 Angular 中,创建一个服务层( token 刷新器),它将每个 API 调用委托(delegate)给服务器(内部使用 http 服务)。
- 此服务的工作是检查 API 响应的状态(如果是 498)并在内部进行额外的调用来刷新 token 。
- 然后,服务可以使用新创建的 token 重新发起原始调用以获取响应。
- 所有 API 服务都会调用 token 刷新器来获取响应。
在更广泛的层面上, token 刷新器是默认 http 服务的包装器,用于执行额外的检查。
这将避免烦人的页面加载并使应用程序更快。
EDIT - Example of HTTP Interceptor
import { Injectable } from "@angular/core";
import { XHRBackend, RequestOptions, Request, RequestOptionsArgs, Response, Http, Headers } from "@angular/http";
import { Store } from "@ngrx/store";
import { Observable } from "rxjs/Rx";
import { Observer } from "rxjs/Observer";
import { Response as ApiResponse } from "../../models/base/response.model";
import { ToastModel } from "../../redux/app-reducers";
import { ReducerActions } from "../../redux/reducer-actions";
@Injectable()
export class HttpInterceptor extends Http {
constructor(private _XHRBackend: XHRBackend,
private _RequestOptions: RequestOptions,
private _ToastStore: Store<ToastModel>,
private _LoaderStore: Store<boolean>) {
super(_XHRBackend, _RequestOptions);
}
public request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
return this.handleResponse(super.request(url, options));
}
public get(url: string, options?: RequestOptionsArgs): Observable<Response> {
this.beforeRequest(url);
return super.get(url, this.getRequestOptionArgs(options));
}
public post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
this.beforeRequest(url, body);
return super.post(url, body, this.getRequestOptionArgs(options));
}
public put(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
this.beforeRequest(url, body);
return super.put(url, body, this.getRequestOptionArgs(options));
}
public delete(url: string, options?: RequestOptionsArgs): Observable<Response> {
this.beforeRequest(url);
return super.delete(url, this.getRequestOptionArgs(options));
}
private getRequestOptionArgs(options?: RequestOptionsArgs): RequestOptionsArgs {
if (options == null) {
options = new RequestOptions();
}
if (options.headers == null) {
options.headers = new Headers();
}
options.headers.append('Content-Type', 'application/json');
return options;
}
private handleResponse(response: Observable<Response>): Observable<Response> {
return response
.catch(this.onCatch)
.do(this.onSuccess.bind(this), this.onError.bind(this))
.finally(this.afterResponse.bind(this));
}
private beforeRequest(url: string, body?: string): void {
this._LoaderStore.dispatch({ type: ReducerActions.Loader.Set, payload: true });
}
private afterResponse(): void {
this._LoaderStore.dispatch({ type: ReducerActions.Loader.Set, payload: false });
}
private onCatch(error: any, caught: Observable<Response>): Observable<Response> {
console.log("interceptor catch called");
return Observable.throw(error);
}
private onSuccess(res: Response): void {
let response: ApiResponse<any> = res.json();
if (!response.message) {
return;
}
let toast: ToastModel = {
text: response.message,
duration: 5000,
type: "success"
};
this._ToastStore.dispatch({ type: ReducerActions.Toast.Update, payload: toast });
}
private onError(error: any): void {
let toast: ToastModel = {
text: "Error occurred!",
duration: 5000,
type: "failure"
};
this._ToastStore.dispatch({ type: ReducerActions.Toast.Update, payload: toast });
}
}
<小时/>
在上面的例子中,handleResponse
回调是做任何你想做的事情的钩子(Hook)。 (在本例中, token 刷新 API 调用)。
我希望这有帮助。 :)
关于javascript - 我如何在 Angular 4中使用刷新 token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48077369/