【问题标题】:What is the right way to configure global authentication http headers in Angular?在 Angular 中配置全局身份验证 http 标头的正确方法是什么?
【发布时间】:2018-02-08 16:55:34
【问题描述】:

我正在尝试在 Angular 2 应用程序中添加基于 JWT 的身份验证。

我收到了来自 Auth0 的 idToken 并将其存储在 LocalStorage 中。现在我想确保对我的 API 的所有传出 http 调用都将具有此标头设置:

授权:承载 e3rere....

当然,我可以在每个 http 调用中手动添加它。但是一劳永逸地配置会更方便。

在 Angular 中正确的做法是什么? (角度 2)

【问题讨论】:

  • 实际上是 Angular 2.x?如果您使用的是 4.3 及更高版本,则可以使用新的 HttpClient 并实现 interceptor。否则,继承Httpthe request options 并使用DI 注入您自己的版本是很常见的。这两种方法已在其他地方记录。
  • Thx @jonrsharpe 我尝试按照上面提到的关于请求选项v2.angular.io/docs/ts/latest/guide/… 的文章进行操作,但标题似乎没有按预期添加。我现在将尝试使用其他地方提到的拦截器。

标签: angular authentication jwt auth0


【解决方案1】:

我在我的 AuthService 中添加了一个方法,用于处理创建标头

@Injectable()
export class AuthenticationService {

    //Other stuff your authentication service might do

    getHeaderWithAuthorization() {
        let currentUser = JSON.parse(localStorage.getItem('currentUser'));
        if (currentUser && currentUser.Token) {

            let headers = new Headers({ 'Content-Type': 'application/json' });
            headers.append('Authorization', 'Bearer ' + currentUser.Token);
            return new RequestOptions({ headers: headers });
        }
    }
}


@Injectable()
export class UserService {

    private baseUrl;
    private options: RequestOptions;

    constructor(private http: Http, private authService: AuthenticationService)             
{
        this.baseUrl = "/api/User/";
        this.options = authService.getHeaderWithAuthorization();
    }

    SaveUser(user) {
        return this.http.post(this.baseUrl + "SaveUser", user, this.options)
            .map((res) => res.json());
    }

}

【讨论】:

  • 感谢分享。但这是我试图避免的,因为我需要在所有服务中重复代码。
【解决方案2】:

我不确定这是否会被认为是最佳解决方案,但我发现它非常有用。

我在 app.module.ts 中添加了这个函数:

 export function authHttpServiceFactory(http: Http, options: RequestOptions, auth: AuthService) {
   return new AuthHttp( new AuthConfig(
       {
         tokenName: 'id_token',
         globalHeaders: [{'Content-Type': 'application/json'}],
         tokenGetter: (() => localStorage.getItem('id_token'))
       }
     ), http, options);
 }
...
providers: [...{
  provide: AuthHttp,
  useFactory: authHttpServiceFactory,
  deps: [ Http, RequestOptions, AuthService ]
},...]

最后我会确保我的服务依赖于 AuthHttp 而不是 Http。

【讨论】:

    【解决方案3】:

    方法一:

    如果您使用的是 Angular 4.3+,那么您可以为此创建一个interceptor,它将充当中介。

    注意:为了使用拦截器,您必须使用 HttpClient 而不是 Http 服务,这是 Angular 4.3 的新增功能,它将通过 Http 服务为您提供 some benefits .

    如果用户已登录,您可以在此处添加标题。

    @Injectable()
    export class AddHeaderInterceptor implements HttpInterceptor {
        intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
           if(UserService.getToken()){
             req.headers.set('Authorization', 'Bearer ' + UserService.getToken());
           }
    
            return next.handle(req);
        }
    }
    

    重要提示:不要忘记在你的应用模块中提供拦截器类。

    import {HTTP_INTERCEPTORS} from '@angular/common/http';
    
    @NgModule({
      providers: [{
        provide: HTTP_INTERCEPTORS,
        useClass: AddHeaderInterceptor,
        multi: true,
      }],
    })
    

    方法2:

    如果您使用的是低于 4.3.0 的版本,那么您可以采用不同的方法,例如扩展 BaseRequestOptions 以将公共标头注入所有请求。

       import {BaseRequestOptions} from '@angular/http';
       @Injectable()
       export class AdddingHeaderOptions extends BaseRequestOptions {
            constructor() {
                super();
                if(UserService.getToken()){
                    this.headers.append('X-Requested-With', 'XMLHttpRequest');
                    this.headers.append('Authorization', 'Bearer ' + UserService.getToken());
                }
            }
        }
    

    现在,您可以将其提供给应用模块文件。

    @NgModule({
        providers   : [
            {provide: RequestOptions, useClass: AdddingHeaderOptions }
        ]
    })
    

    【讨论】:

    • 您应该注意,这只适用于较新版本的 Angular; @angular/common/http 是在 4.3.0 中引入的,许多应用程序将使用 @angular/http
    • 哦,我明白了,在那种情况下,我认为这可能是一个更大的变化。因此,我将返回并使用围绕 http 的包装类。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-23
    • 1970-01-01
    • 2015-05-09
    • 2019-06-19
    • 1970-01-01
    • 2023-03-09
    相关资源
    最近更新 更多