2017-01-11 2 views
1

나는 Angular2, Angular-cli, Spring Boot 1.4.0 및 jwt를 사용합니다. Angular2 클라이언트에 로그인 할 때 jwt 토큰을 얻을 수 없습니다.Angular2 스프링 부트 JWT가 없음 응답 헤더

내 보안 설정은 다음과 같습니다

@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은 다음과 같습니다 enter image description here

하지만 : 나는 우체부와 요청에 사인을 보낼 때

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); 
    } 
    } 

, 나는이 같은 응답을받을 로그인 요청을 보내십시오 내 Angular2 응용 프로그램 "Authorization"사용자 정의 헤더라는 응답 헤더를받을 수 없습니다. 내 응답 개체는 다음과 같습니다. enter image description here

그러나 브라우저 콘솔을 보면 내 costum 헤더 "Authorization"이 표시됩니다. enter image description here

내 Angular2 코드는 다음과 같습니다

@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은 다음과 같습니다

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 토큰을받을 및 브라우저 로컬 스토리지를 추가 할 수 없습니다?

답변

0

Angular2 앱과 springboot를 다른 포트에서 실행하고 있습니까? 그렇다면 스프링 부트 응용 프로그램에서 CORS를 활성화 했습니까?

는 기본적으로 응용 프로그램에 사용자 지정 헤더를 노출하지 않습니다 체크 아웃, 각도보다 springboot JWT 작업에 대한 Angualr2 포스트 헤더

this.http.post('http://localhost:9090/api/user/login', 
    { withCredentials: true }, 
    this.cred) 

Springboot JWT Starter

1

브라우저를 withCredentials: true를 추가합니다.

당신은 헤더가 콘솔 dev에 존재하는 경우에도 그들은 당신이 서버 응용 프로그램에 의해 노출되지 않는 경우 앱이 읽을 수없는 백엔드 고르의 설정에

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

참고 다음 헤더가 필요합니다 .

0

문제를 해결하는 가장 좋은 방법은 https://spring.io/blog/2015/06/08/cors-support-in-spring-framework에 설명 된대로 응용 프로그램에 cors 구성을 추가하는 것입니다. 다음과 같이 할 수도 있습니다.

@Configuration 
public class RestConfigs { 
    @Bean 
    public CorsFilter corsFilter() { 
     UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 
     CorsConfiguration config = new CorsConfiguration(); 
     config.setAllowCredentials(true); 
     config.addAllowedOrigin("*"); 
     config.addExposedHeader(MyUtils.AUTHENTICATION); //Header String 
     config.addAllowedHeader("*"); 
     config.addAllowedMethod("OPTIONS"); 
     config.addAllowedMethod("GET"); 
     config.addAllowedMethod("POST"); 
     config.addAllowedMethod("PUT"); 
     config.addAllowedMethod("DELETE"); 
     source.registerCorsConfiguration("/**", config); 
     return new CorsFilter(source); 
    } 
관련 문제