symfony 不在标头中获取令牌

Posted

技术标签:

【中文标题】symfony 不在标头中获取令牌【英文标题】:symfony don't fetch token in header 【发布时间】: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 配置吗?您也可以尝试从头开始设置,可能在生成密钥时出现问题。 【参考方案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, 使用类:错误拦截器, 多:真

【讨论】:

感谢您的提示,这对最佳实践很有好处,但它不能解决我的问题

以上是关于symfony 不在标头中获取令牌的主要内容,如果未能解决你的问题,请参考以下文章

从 Symfony3 中经过身份验证的用户 (HWIOAuth) 获取 Angular2 中的 JWT 令牌

Symfony 3中http标头之间的冲突

Symfony2 中的 JWT 令牌

Symfony 4 HTTP 缓存标头在探查器和浏览器中不同

通过使用 Symfony2 的 API 使用用户密码进行身份验证

Jwt 令牌解码 - Symfony 4