【问题标题】:symfony don't fetch token in headersymfony 不在标头中获取令牌
【发布时间】:2020-03-23 11:47:14
【问题描述】:

我正在使用 jwt 解决问题。事实上,我使用 Angular 来使用由 Symfony 3.4 制作的 API,它会生成一个令牌,但是当我发送它时,我会使用这样的拦截器设置标题。

import {Injectable} from '@angular/core';
import {HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
import {LoginService} from '../../services/authServices/login.service';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {

    constructor(private auth: LoginService) {}

    intercept(req: HttpRequest<any>, next: HttpHandler) {

        if (req.url.indexOf('/admin') !== -1) {
            const authToken: string = `Bearer ${this.auth.getJwtToken()}`;

            if (authToken) {
                console.log('sending token to perform API fetch...');

                const authReq = req.clone({ setHeaders: { 'Authorization': authToken, 'Content-Type': 'application/json'} });
                console.log(authReq);

                return next.handle(
                    authReq
                );
            }

        }

        return next.handle(req);
    }
}

但是当我尝试从受保护的路由中获取资源时,Symfony 返回了一个未经授权的响应 401,似乎 Symfony 也没有提取令牌

这是我在 Symfony 3.4 上的 lexik jwt 配置文件

lexik_jwt_authentication:
    private_key_path:       '%kernel.project_dir%/config/jwt/private.pem' # required for token creation
    public_key_path:       '%kernel.project_dir%/config/jwt/private.pem'  # required for token verification
    pass_phrase:      "%user_pass%" # required for token creation, usage of an environment variable is recommended
    token_ttl:        3600
    user_identity_field: id  # key under which the user identity will be stored in the token payload
    clock_skew: 0

    # token encoding/decoding settings
    encoder:
        # token encoder/decoder service - default implementation based on the lcobucci/jwt library
        service:            lexik_jwt_authentication.encoder.lcobucci

        # encryption algorithm used by the encoder service
        signature_algorithm: RS256

    # token extraction settings
    token_extractors:
        # look for a token as Authorization Header
        authorization_header:
            enabled: true
            prefix:  Bearer
            name:    Authorization

        # check token in a cookie
        cookie:
            enabled: false
            name:    BEARER

        # check token in a query string parameter
        query_parameter:
            enabled: false
            name:    bearer

【问题讨论】:

  • 你试过在没有 Angular 的情况下这样做吗?例如,您可以尝试使用 Postman 来查看 Symfony 是否返回一个令牌,以及当您在标题中手动设置此令牌时会发生什么。这样,您可以确定问题出在 Angular 还是 Symfony。
  • 我试过了,实际上似乎 Symfony 生成的令牌是无效的,为了验证它,我将令牌复制并粘贴到 jwt 官方网站上,它是无效的,所以我现在的问题是如何处理那个。
  • 奇怪,你用的是LexikJWTAuthenticationBundle吗?我最近使用它制作了一个 API(尽管在 Symfony 4.4 中),它就像一个魅力。如果没有,你用的是什么?
  • 是的,我正在使用 LexikJWTAuthenticationBundle 和 symfony 3.4
  • 您能发布您的 LexikJWTAB 配置吗?您也可以尝试从头开始设置,可能在生成密钥时出现问题。

标签: angular symfony jwt


【解决方案1】:

在任何情况下使用 Interceptor 的最佳方式是它会有所帮助

export class ErrorInterceptor implements HttpInterceptor {
intercept (req:HttpRequest<any> , next : HttpHandler): Observable<HttpEvent<any>>{
    return next.handle(req).pipe(
        catchError(error=>{
            if(error instanceof HttpErrorResponse){
                const applicationError = error.headers.get('Application-Error');
                if(applicationError){
                    console.error(applicationError);
                    return throwError(applicationError);
                }
                // Model Error
                const serverError = error.error;
                let modelStateErrors='';
                if(serverError && typeof serverError ==='object'){
                    for(const key in serverError){
                        if(serverError[key]){
                            modelStateErrors += serverError[key] + '\n';
                        }
                    }                      
                }
                // un authorized errors
                if(error.status === 401){
                    return throwError (error.statusText);
                }
                return throwError (modelStateErrors || serverError || 'Server Error')
            }
        })
    )   
}

}

导出常量 ErrorInterceptorProvider ={ 提供:HTTP_INTERCEPTORS, 使用类:错误拦截器, 多:真}

【讨论】:

  • 感谢您的提示,这对最佳实践很有好处,但它不能解决我的问题
猜你喜欢
  • 2021-07-27
  • 2017-07-25
  • 1970-01-01
  • 2019-07-22
  • 1970-01-01
  • 2018-07-26
  • 2018-07-05
  • 2020-11-16
  • 2020-08-10
相关资源
最近更新 更多