2016-11-10 134 views
0

我在春天使用restful服務,並且已經實現了用於身份驗證和授權的Json Web Token(JWT)。登錄後,將正確的身份驗證令牌返回給請求用戶。在每個請求上,我都檢查請求頭中的令牌並驗證令牌。代碼如下。在Angular 2中設置授權標頭

@Override 
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) 
     throws ServletException, IOException { 
    String authToken = request.getHeader(this.tokenHeader); 
    System.out.println(authToken + "  ##########################"); 
    String username = flTokenUtil.getUsernameFromToken(authToken); 
    if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { 
     UserDetails userDetails = this.userDetailsService.loadUserByUsername(username); 
     if (flTokenUtil.validateToken(authToken, userDetails)) { 
      UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
        userDetails, null, userDetails.getAuthorities()); 
      authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); 
      SecurityContextHolder.getContext().setAuthentication(authentication); 
     } 
    } 

    chain.doFilter(request, response); 

} 

而我正在使用角2作爲前端框架。現在,在獲得身份驗證令牌後,我使用「POSTMAN」請求安全資源,它的工作原理非常完美,並且過濾器中收到了令牌,並且一切順利。我在「授權」標題中設置了令牌。 現在的問題是,當我做同樣的事情使用角2令牌在過濾器中爲空,但螢火蟲顯示「授權」標頭設置併發送成功。我這樣做

let token = ""; 
    if (undefined != this._tokenService.getToken()) { 
     token = this._tokenService.getToken().getToken() 
    } 
    let header: Headers = new Headers(); 
    header.append('Content-Type', 'application/json'); 
    header.append('Authorization', token); 
    let options = new RequestOptions({headers: header}); 

    return this.http.get(url, options) 
     .map(res => { 
      console.log(res.status) 
      if (res.status == 200) { 
       return res.json(); 
      } else if (res.status == 401) { 
       return null; 
      } else { 
       throw new Error('This request has failed ' + res.status); 
      } 
     }); 

我在做什麼錯了?以角度設置標題的正確方法是什麼2.我該如何解決此問題?

+0

如果您CONSOLE.LOG的this._tokenService.getToken()。爲gettoken()是令牌呢? 嘗試在chrome的開發人員工具中調試請求,您可以看到授權標頭是否正確發送。 –

+0

是設置了令牌。我檢查了它。 –

+0

它也可以在螢火蟲的請求標題中看到 –

回答

0

添加承載您AUTH標題和內容類型頭也喜歡:

headers.append("content-type", "application/x-www-form-urlencode"); 
headers.append("Authorization", "Bearer " + this.accessToken); 
+0

它不應該也冒號嗎? '持票人:'或者是可選的? –

+0

不知道...我發佈的東西已經工作了幾個月.. –

+0

我認爲這是服務器端問題,因爲第一次當我請求登錄和時間令牌爲空,並過濾器接收「承載」作爲令牌,所以它意味着收到登錄請求的令牌,但在此之後,其他請求在服務器端顯示爲空。 –

1

如果你想要一個更永久的解決方案,我已經得到了一個給你。

通過繼承angular的http服務,您可以注入subclassed版本,然後始終添加標頭。

import { 
    Http, 
    ConnectionBackend, 
    Headers, 
    Request, 
    RequestOptions, 
    RequestOptionsArgs, 
    Response, 
    RequestMethod, 
} from '@angular/http'; 
import { Observable } from 'rxjs/Observable'; 
import { ErrorObservable } from 'rxjs/observable/ErrorObservable'; 

// A service that can get the logged in users jwt token as an observable 
import { SecurityService } from './security.service'; 

// A service that handles cookies (angular2-cookie) 
import { CookieService } from '../cookie'; 

/** 
* Custom Http client that handles conversions to json, adds CSRF token, and jwt token and redirects to signin if token is missing 
*/ 
export class SecureHttp extends Http { 

    constructor(
    backend: ConnectionBackend, 
    defaultOptions: RequestOptions, 
    private securityService: SecurityService, 
    private cookieService: CookieService 
) { 
    super(backend, defaultOptions); 
    } 

    request(url: string | Request, options?: RequestOptionsArgs): Observable<any> { 
    if (typeof url === 'string') { 
     return this.get(url, options); // Recursion: transform url from String to Request 
    } 

    return this.sendRequest(url, options); 
    } 

    get(url: string, options?: RequestOptionsArgs): Observable<any> { 
    return this.sendRequest({ method: RequestMethod.Get, url: url, body: '' }, options); 
    } 

    post(url: string, body: string, options?: RequestOptionsArgs): Observable<any> { 
    return this.sendRequest({ method: RequestMethod.Post, url: url, body: body }, options); 
    } 

    put(url: string, body: string, options?: RequestOptionsArgs): Observable<any> { 
    return this.sendRequest({ method: RequestMethod.Put, url: url, body: body }, options); 
    } 

    delete(url: string, options?: RequestOptionsArgs): Observable<any> { 
    return this.sendRequest({ method: RequestMethod.Delete, url: url, body: '' }, options); 
    } 

    patch(url: string, body: string, options?: RequestOptionsArgs): Observable<any> { 
    return this.sendRequest({ method: RequestMethod.Patch, url: url, body: body }, options); 
    } 

    head(url: string, options?: RequestOptionsArgs): Observable<any> { 
    return this.sendRequest({ method: RequestMethod.Head, url: url, body: '' }, options); 
    } 

    private sendRequest(requestOptionsArgs: RequestOptionsArgs, options?: RequestOptionsArgs): Observable<any> { 

    let requestOptions = new RequestOptions(requestOptionsArgs); 

    // Convert body to stringified json if it's not a string already 
    if (typeof requestOptions.body !== 'string') { 
     requestOptions.body = JSON.stringify(requestOptions.body); 
    } 

    // Get xsrf token from spring security cookie 
    // by adding .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) 
    const csrfToken: string = this.cookieService.get('XSRF-TOKEN'); 

    let baseOptions: RequestOptions = new RequestOptions({ 
     headers: new Headers({ 
     'Content-Type': 'application/json', 
     'X-Requested-With': 'XMLHttpRequest', 
     'X-XSRF-TOKEN': csrfToken 
     }) 
    }); 

    return this.securityService.accessToken$.mergeMap(token => { 

     // If there is a token we add it to the baseOptions 
     if (token) { 
     baseOptions.headers.set('Authorization', 'Bearer ' + token); 
     } 

     // We create a request from the passed in method, url, body and merge our base options in there 
     let request = new Request(baseOptions.merge(requestOptions)); 

     return super.request(request, options) 
     .map(res => res.json()) 
     .catch(this.errorHandler); 
    }); 
    } 

    private errorHandler(errorResponse: Response): Observable<any> | ErrorObservable { 
    if (errorResponse.status === 401) { 
     console.log('redirecting to login'); 
     window.location.href = '/login'; 
     return Observable.empty(); 
    } 

    // If it's a serious problem we can log it to a service if we want to 
    if (errorResponse.status === 500) { 
     // this.errorReporter.logError(errorResponse); 
    } 

    console.error(errorResponse); 

    return Observable.throw(errorResponse.text().length > 0 ? errorResponse.json() : { status: 'error' }); 
    } 
} 

然後你的模塊

export function secureHttpFactory(backend: XHRBackend, defaultOptions: RequestOptions, securityService: SecurityService, cookieService: CookieService) { 
    return new SecureHttp(backend, defaultOptions, securityService, cookieService); 
} 

@NgModule({ 
    imports: [ 
    HttpModule, 
    CookieModule, 
    StorageModule, 
    ], 
    declarations: [ 
    ...DIRECTIVES, 
    ...COMPONENTS, 
    ], 
    exports: [ 
    ...DIRECTIVES, 
    ] 
}) 
export class SecurityModule { 

    // Only create on instance of these 
    static forRoot(): ModuleWithProviders { 
    return { 
     ngModule: SecurityModule, 
     providers: [ 
     SecurityService, 
     { 
      provide: SecureHttp, 
      useFactory: secureHttpFactory, 
      deps: [XHRBackend, RequestOptions, SecurityService, CookieService] 
     } 
     ] 
    }; 
    } 

}