本文介绍了Angular2 Spring Boot JWT 缺少响应头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 Angular2、Angular-cli、Spring Boot 1.4.0 和 jwt.当我登录我的 Angular2 客户端时,我无法获得 jwt 令牌.

I use Angular2, Angular-cli, Spring Boot 1.4.0 and jwt. When I sign in my Angular2 client I can not get jwt token.

我的安全配置是:

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.csrf().disable() // disable csrf for our requests.
                .authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/api/user/signup").permitAll()
                .antMatchers(HttpMethod.POST, "/api/user/login").permitAll()
                .anyRequest().authenticated()
                .and()
                // We filter the api/login requests
                .addFilterBefore(new JWTLoginFilter("/api/user/login", authenticationManager()), UsernamePasswordAuthenticationFilter.class)
                // And filter other requests to check the presence of JWT in header
                .addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
               .permitAll().and().csrf().disable();
    }
}

我的 TokenAuthenticationService 是:

My TokenAuthenticationService is :

public class TokenAuthenticationService {

    private final long EXPIRATIONTIME = 1000 * 60 * 60 * 24 * 10; // 10 days
    private final String secret = "ThisIsASecret";
    private final String tokenPrefix = "Bearer";
    private final String headerString = "Authorization";
    public void addAuthentication(HttpServletResponse response, String username)
    {
        // We generate a token now.
        String JWT = Jwts.builder()
                    .setSubject(username)
                    .setExpiration(new Date(System.currentTimeMillis() + EXPIRATIONTIME))
                    .signWith(SignatureAlgorithm.HS512, secret)
                    .compact();
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.setHeader(headerString, tokenPrefix + " "+ JWT);
        response.getHeaderNames().stream()
    .forEach(System.out::println);
    }
   }

当我向邮递员发送登录请求时,我收到如下回复:

When I send sign in request with postman, I recieve response like this:

但我发送登录请求我的 Angular2 应用程序我无法收到名为授权"自定义标头的响应标头.我的响应对象是这样的:

But I send sign in request my Angular2 application I can not recieve response header named "Authorization" custom header. My response object is like this:

但是我看浏览器控制台我看到了我的服装标题授权".

But I look browser console I see my costum header "Authorization".

我的 Angular2 代码是:

My Angular2 code is:

@Injectable()
export class LoginService {
  private authEvents: Subject<AuthEvent>;
  private cred: AccountCredentials;

  constructor(private http: JsonHttpService ){
    this.authEvents = new Subject<AuthEvent>();
    this.cred = new AccountCredentials();
  }


  login(email: string, password: string) {
    this.cred.password = password;
    this.cred.username = email;
    return this.http.post('http://localhost:9090/api/user/login', this.cred)
    .do((resp: Response) => {
      localStorage.setItem('jwt', resp.headers.get('Authorization'));
      this.authEvents.next(new DidLogin());
    });
  }

  logout(): void {
    localStorage.removeItem('jwt');
    this.authEvents.next(new DidLogout());
  }

  isSignedIn(): boolean {
    return localStorage.getItem('jwt') !== null;
  }
}

export class DidLogin {
}
export class DidLogout {
}

export type AuthEvent = DidLogin | DidLogout;

我的 JsonHttpService 是:

And My JsonHttpService is:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import {
  Http,
  RequestOptionsArgs,
  RequestOptions,
  Response,
  Headers
} from '@angular/http';

const mergeAuthToken = (options: RequestOptionsArgs = {}) => {
  let newOptions = new RequestOptions({}).merge(options);
  let newHeaders = new Headers(newOptions.headers);
  const jwt = localStorage.getItem('jwt');

  if (jwt && jwt !== 'null') {
    newHeaders.set('Authorization', jwt);
  }
 newHeaders.set('content-type', 'application/x-www-form-urlencoded; charset=utf-8');

  // newHeaders.set('Access-Control-Allow-Origin', '*');
  newOptions.headers = newHeaders;
  return newOptions;
};

@Injectable()
export class JsonHttpService {

  constructor(private http: Http) { }


  get(url: string, options?: RequestOptionsArgs): Observable<Response> {
    return this.http.get(url, mergeAuthToken(options));
  }

  post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
    return this.http.post(url, body, mergeAuthToken(options));
  }

  put(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
    return this.http.put(url, body, mergeAuthToken(options));
  }

  delete(url: string, options?: RequestOptionsArgs): Observable<Response> {
    return this.http.delete(url, mergeAuthToken(options));
  }

  patch(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
    return this.http.patch(url, body, mergeAuthToken(options));
  }

  head(url: string, options?: RequestOptionsArgs): Observable<Response> {
    return this.http.head(url, mergeAuthToken(options));
  }


}

那么为什么我无法收到我的 jwt 令牌并添加我的浏览器 localStorage?

So why I can not recieve my jwt token and add my browser localStorage?

推荐答案

默认情况下,浏览器不会向应用公开自定义标头.

The browser does not expose custom headers to the app by default.

您的后端 Cors 配置中需要以下标头

You will need the following header in your Backend Cors config

'Access-Control-Expose-Headers' 'Authorization';

请注意,即使开发控制台中存在标头,如果您的服务器应用程序未公开这些标头,您的应用也无法读取它们.

Note that even if the headers are present in the dev console your app can't read them if they are not exposed by you server application.

这篇关于Angular2 Spring Boot JWT 缺少响应头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-11 06:46