Angular 5 HTTP客户端在响应标头中缺少"授权"

Cas*_*ils 8 http jwt angular

我正在使用JWT(JSON Web Tokens)作为将人员记录到系统中的一部分.执行此操作的代码如下:

this.http.post(url, JSON.stringify({ username: username, password: password }), { observe: 'response' })
      .subscribe((response: HttpResponse<any>) => {
Run Code Online (Sandbox Code Playgroud)

发送username和发送password到服务器时,Response对象包含Header中的加密授权.

作为标题的一部分包括Authorization条目和Pragma条目.在Authorization有正确定义的令牌(和它的作品).Pragma也被定义为no-cache

来自Chrome中的网络标签:

在此输入图像描述

但是当运行代码来处理响应头时,Authorization标头不存在.

 adminLogin(username, password) {
    let url = `${this._apiRoot}/login`;
    let tokenResp = {};

    this.http.post(url, JSON.stringify({ username: username, password: password }), { observe: 'response' })
      .subscribe((response: HttpResponse<any>) => {

        console.log(" ---- begin response ----");
        console.log( response );
        console.log(" ---- end response ----");

        let token = response.headers.get("Authorization");

        console.log(" ---- begin token ----");
        console.log ( token );
        console.log(" ---- end token ----");

        let pragma = response.headers.get("pragma");

        console.log(" ---- begin pragma ----");
        console.log ( pragma );
        console.log(" ---- end pragma ----");
Run Code Online (Sandbox Code Playgroud)

执行代码的结果:

在此输入图像描述

从执行的代码中,可以看到尝试在获取时Authorization返回.到底是怎么回事?nullPragmano-cache

UPDATE

谢谢大家的信息.

我按照这里的信息:https: //github.com/angular/angular/issues/13554

并对java代码进行了更改:

@Override
    protected void successfulAuthentication(HttpServletRequest req,
            HttpServletResponse res, FilterChain chain, Authentication auth)
            throws IOException, ServletException {
        String username = ((User) auth.getPrincipal()).getUsername();
        ApplicationUser user = applicationUserRepository
                .findByUsername(username);

        String token = Jwts
                .builder()
                .setSubject(((User) auth.getPrincipal()).getUsername())
                .claim("id", user.getId())

            [... snip ...]

            res.addHeader("Access-Control-Expose-Headers", "Authorization");
            res.addHeader(SecurityConstants.HEADER_STRING,SecurityConstants.TOKEN_PREFIX + token);

    }
Run Code Online (Sandbox Code Playgroud)

再次感谢!

Mor*_*kop 4

为了解决这个问题,我们需要从后端公开所需的标头,并使用和编写自定义的HttpInterceptor

NodeJs API 示例authorization:从后端公开标头

res.setHeader('Access-Control-Expose-Headers', 'authorization'); 
res.setHeader('authorization', 'foo-bar');
Run Code Online (Sandbox Code Playgroud)

角拦截器示例

@Injectable()
export class HttpInterceptorService implements HttpInterceptor {
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<any> {
    return next.handle(request).pipe(
      tap(response => {
        if (response.headers) {
          console.log('Header keys', response.headers.keys());
          console.log('Authorization: ', response.headers.get('authorization'));
        }
      }),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

最后我们将拦截器添加到我们的模块提供程序中

import { NgModule } from '@angular/core';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { HttpInterceptorService } from './http-interceptor.service';

@NgModule({
  ...
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: HttpInterceptorService, multi: true },
  ],
})
export class AppModule {}
Run Code Online (Sandbox Code Playgroud)

示例代码存储库对于了解有关 Angular HttpInterceptor 的更多信息很有用