【问题标题】:jwt token not found when i pass in username and password in curl当我在 curl 中传递用户名和密码时找不到 jwt 令牌
【发布时间】:2021-07-31 15:15:32
【问题描述】:

我想在我的 symfony 项目中使用 jwt 令牌。但我有一个问题,因为当我使用:curl.exe -X POST -H "Content-Type: application/json" http://localhost:81/api/login_check -d '{"username": "f.djawid@outlook.com","password":"000000"}'

我明白了:{"code":401,"message":"JWT Token not found"}

这是我的 security.yml:

#/config/packages/security.yml

security:
    encoders:
        App\Entity\User:
            algorithm: auto




    # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
    providers:
        # used to reload user from session & other features (e.g. switch_user)
        app_user_provider:
            entity:
                class: App\Entity\User
                property: email
        # used to reload user from session & other features (e.g. switch_user)
        # used to reload user from session & other features (e.g. switch_user)
        # used to reload user from session & other features (e.g. switch_user)
    firewalls:  
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        api:
            pattern: ^/api
            stateless: true
            guard:
                authenticators:
                    - lexik_jwt_authentication.jwt_token_authenticator
        login:
            pattern: ^/api/login
            stateless: true
            anonymous: true
            json_login:
                check_path: /api/login_check
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure            
            
        main:
            anonymous: true
                

    # Easy way to control access for large sections of your site
    # Note: Only the *first* access control that matches will be used
    access_control:
        - { path: ^/api/docs, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api/login,       roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api,       roles: IS_AUTHENTICATED_FULLY }

如您所见,我使用 lexikJWTAthenticationBundle。我用 ssl 制作了私钥和公钥。

我使用 docker 来运行我的 localhost 所在的 apache 服务器。这是我的虚拟主机配置:

#/.docker/config/sf4.conf

<VirtualHost *:80>

        Define server_name sf4.local
        Define basedocroot  /home/wwwroot/sf4
        Define docrootweb   ${basedocroot}/public
        Define logdir   /var/log/apache2/

        <FilesMatch .php$>
         SetHandler "proxy:fcgi://sf4_php:9000"
        </FilesMatch>

        ServerName ${server_name}
        DocumentRoot ${docrootweb}
        ErrorLog ${logdir}/error.log
        CustomLog ${logdir}/access.log Combined

        RewriteEngine On
        RewriteCond %{HTTP:Authorization} ^(.*)
        RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]

        <Directory ${docrootweb}>
            AllowOverride All
            Require all granted
        </Directory>

        <Directory ${basedocroot}/var>
            <IfModule mod_authz_core.c>
                Require all denied
            </IfModule>
            <IfModule !mod_authz_core.c>
                Order deny,allow
                Deny from all
            </IfModule>
        </Directory>

        <Directory ${docrootweb}>
            DirectoryIndex ${docrootweb}/index.php
            <IfModule mod_negotiation.c>
                Options -MultiViews
            </IfModule>

            <IfModule mod_rewrite.c>
                RewriteEngine On
                RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
                RewriteRule ^(.*) - [E=BASE:%1]

                RewriteCond %{HTTP:Authorization} .
                RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

                RewriteCond %{ENV:REDIRECT_STATUS} ^$
                RewriteRule ^index\.php(?:/(.*)|$) %{ENV:BASE}/$1 [R=301,L]

                RewriteCond %{REQUEST_FILENAME} -f
                RewriteRule ^ - [L]

                RewriteRule ^ %{ENV:BASE}/index.php [L]
            </IfModule>

            <IfModule !mod_rewrite.c>
                <IfModule mod_alias.c>
                    RedirectMatch 302 ^/$ /index.php/
                </IfModule>
            </IfModule>
        </Directory>

        Undefine server_name
        Undefine basedocroot
        Undefine docrootweb
        Undefine logdir
</VirtualHost>


我在另一篇文章中发现,解决方案可能是如果我使用 Apache,我必须添加 Rewrite for Authorization,但它已经添加到那里,并且在使用 curl 时它仍然没有发布 jwt 令牌,就像我上面所做的那样。

我还使用 make:user 创建了用户实体,并在表 user 中添加了用户名、角色和密码值。在 curl 你可以看到我使用 000000 作为密码。在数据库中,此密码使用 argon2i 进行哈希处理。

我真的不知道为什么我看不到 jwt 令牌。我在互联网上到处寻找,但似乎没有什么对我有用。

编辑

我在 lexik_jwt_authentication.yml 中也有这个:

#/config/packages/lexik_jwt_authentication.yml

lexik_jwt_authentication:
    secret_key: '%env(resolve:JWT_SECRET_KEY)%'
    public_key: '%env(resolve:JWT_PUBLIC_KEY)%'
    pass_phrase: '%env(JWT_PASSPHRASE)%'

这就是我在 .env 文件中定义的内容:

# /.env
JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem
JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem
JWT_PASSPHRASE=accountingmodule

此外,当我在 security.yml 中交换登录和 api 标头时,我会收到此错误:

{"type":"https:\/\/tools.ietf.org\/html\/rfc2616#section-10","title":"An error occurred","status":400,"detail":"Invalid JSON.","class":"Symfony\\Component\\HttpKernel\\Exception\\BadRequestHttpException","trace":[{"namespace":"","short_class":"","class":"","type":"","function":"","file":"\/home\/wwwroot\/sf4\/vendor\/symfony\/security-http\/Firewall\/UsernamePasswordJsonAuthenticationListener.php","line":108,"args":[]},{"namespace":"Symfony\\Component\\Security\\Http\\Firewall","short_class":"UsernamePasswordJsonAuthenticationListener","class":"Symfony\\Component\\Security\\Http\\Firewall\\UsernamePasswordJsonAuthenticationListener","type":"->","function":"authenticate","file":"\/home\/wwwroot\/sf4\/vendor\/symfony\/security-bundle\/Debug\/WrappedLazyListener.php","line":49,"args":[["object","Symfony\\Component\\HttpKernel\\Event\\RequestEvent"]]},{"namespace":"Symfony\\Bundle\\SecurityBundle\\Debug","short_class":"WrappedLazyListener","class":"Symfony\\Bundle\\SecurityBundle\\Debug\\WrappedLazyListener","type":"->","function":"authenticate","file":"\/home\/wwwroot\/sf4\/vendor\/symfony\/security-http\/Firewall\/AbstractListener.php","line":27,"args":[["object","Symfony\\Component\\HttpKernel\\Event\\RequestEvent"]]},{"namespace":"Symfony\\Component\\Security\\Http\\Firewall","short_class":"AbstractListener","class":"Symfony\\Component\\Security\\Http\\Firewall\\AbstractListener","type":"->","function":"__invoke","file":"\/home\/wwwroot\/sf4\/vendor\/symfony\/security-bundle\/Debug\/TraceableFirewallListener.php","line":62,"args":[["object","Symfony\\Component\\HttpKernel\\Event\\RequestEvent"]]},{"namespace":"Symfony\\Bundle\\SecurityBundle\\Debug","short_class":"TraceableFirewallListener","class":"Symfony\\Bundle\\SecurityBundle\\Debug\\TraceableFirewallListener","type":"->","function":"callListeners","file":"\/home\/wwwroot\/sf4\/vendor\/symfony\/security-http\/Firewall.php","line":98,"args":[["object","Symfony\\Component\\HttpKernel\\Event\\RequestEvent"],["object","Generator"]]},{"namespace":"Symfony\\Component\\Security\\Http","short_class":"Firewall","class":"Symfony\\Component\\Security\\Http\\Firewall","type":"->","function":"onKernelRequest","file":"\/home\/wwwroot\/sf4\/vendor\/symfony\/event-dispatcher\/Debug\/WrappedListener.php","line":126,"args":[["object","Symfony\\Component\\HttpKernel\\Event\\RequestEvent"],["string","kernel.request"],["object","Symfony\\Component\\HttpKernel\\Debug\\TraceableEventDispatcher"]]},{"namespace":"Symfony\\Component\\EventDispatcher\\Debug","short_class":"WrappedListener","class":"Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener","type":"->","function":"__invoke","file":"\/home\/wwwroot\/sf4\/vendor\/symfony\/event-dispatcher\/EventDispatcher.php","line":264,"args":[["object","Symfony\\Component\\HttpKernel\\Event\\RequestEvent"],["string","kernel.request"],["object","Symfony\\Component\\HttpKernel\\Debug\\TraceableEventDispatcher"]]},{"namespace":"Symfony\\Component\\EventDispatcher","short_class":"EventDispatcher","class":"Symfony\\Component\\EventDispatcher\\EventDispatcher","type":"->","function":"doDispatch","file":"\/home\/wwwroot\/sf4\/vendor\/symfony\/event-dispatcher\/EventDispatcher.php","line":239,"args":[["array",[["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"]]],["string","kernel.request"],["object","Symfony\\Component\\HttpKernel\\Event\\RequestEvent"]]},{"namespace":"Symfony\\Component\\EventDispatcher","short_class":"EventDispatcher","class":"Symfony\\Component\\EventDispatcher\\EventDispatcher","type":"->","function":"callListeners","file":"\/home\/wwwroot\/sf4\/vendor\/symfony\/event-dispatcher\/EventDispatcher.php","line":73,"args":[["array",[["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"],["object","Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"]]],["string","kernel.request"],["object","Symfony\\Component\\HttpKernel\\Event\\RequestEvent"]]},{"namespace":"Symfony\\Component\\EventDispatcher","short_class":"EventDispatcher","class":"Symfony\\Component\\EventDispatcher\\EventDispatcher","type":"->","function":"dispatch","file":"\/home\/wwwroot\/sf4\/vendor\/symfony\/event-dispatcher\/Debug\/TraceableEventDispatcher.php","line":168,"args":[["object","Symfony\\Component\\HttpKernel\\Event\\RequestEvent"],["string","kernel.request"]]},{"namespace":"Symfony\\Component\\EventDispatcher\\Debug","short_class":"TraceableEventDispatcher","class":"Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcher","type":"->","function":"dispatch","file":"\/home\/wwwroot\/sf4\/vendor\/symfony\/http-kernel\/HttpKernel.php","line":134,"args":[["object","Symfony\\Component\\HttpKernel\\Event\\RequestEvent"],["string","kernel.request"]]},{"namespace":"Symfony\\Component\\HttpKernel","short_class":"HttpKernel","class":"Symfony\\Component\\HttpKernel\\HttpKernel","type":"->","function":"handleRaw","file":"\/home\/wwwroot\/sf4\/vendor\/symfony\/http-kernel\/HttpKernel.php","line":80,"args":[["object","Symfony\\Component\\HttpFoundation\\Request"],["integer",1]]},{"namespace":"Symfony\\Component\\HttpKernel","short_class":"HttpKernel","class":"Symfony\\Component\\HttpKernel\\HttpKernel","type":"->","function":"handle","file":"\/home\/wwwroot\/sf4\/vendor\/symfony\/http-kernel\/Kernel.php","line":201,"args":[["object","Symfony\\Component\\HttpFoundation\\Request"],["integer",1],["boolean",true]]},{"namespace":"Symfony\\Component\\HttpKernel","short_class":"Kernel","class":"Symfony\\Component\\HttpKernel\\Kernel","type":"->","function":"handle","file":"\/home\/wwwroot\/sf4\/public\/index.php","line":25,"args":[["object","Symfony\\Component\\HttpFoundation\\Request"]]}]}

【问题讨论】:

    标签: php docker symfony curl jwt


    【解决方案1】:

    curl -H 'Accept: application/json' -H "Authorization: Bearer AAAATOKENBBBBB" https://hostname/api/myresource

    您使用以下 curl:

    curl.exe -X POST -H "Content-Type: application/json" http://localhost:81/api/login_check -d '{"username": "f.djawid@outlook.com","password":"000000"}'
    

    这看起来像是一个登录请求。

    关于身份验证的 API 有两种类型的请求:

    1. 经过身份验证的请求
    2. 公开请求。

    经过身份验证的请求在标头中需要 JWT 令牌:{'Authorization': 'Bearer token'} 并且您的 API 端应该检查这一点,如果没有给出 JWT,则返回错误。

    公共请求不应检查 API 中的 JWT。 授权部分有一些公共请求:

    • /auth/登录
    • /auth/忘记密码
    • /auth/signin

    Auth 部分中经过身份验证的请求示例:

    • /auth/profile(更改配置文件)

    查看您正在调用的端点:/api/login_check 它在哪里指定这是一个未经身份验证的请求? 不知道 Symfony,但我看到了:{path: ^/api} /api/login_check 根据标准正则表达式规则匹配。

    希望对您有所帮助。

    【讨论】:

    • 您的意思是未经身份验证的请求访问控制?我已经指定只有 ^/api 需要身份验证(IS_AUTHENTICATED_FULLY)并且路径 /api/login_check 使用未经身份验证的登录名(IS_AUTHENTICATED_ANONYMOUSLY)。
    • 你确定第二个路径(^/api/login)匹配吗?
    • 我正在关注帖子中所说的一切:github.com/lexik/LexikJWTAuthenticationBundle/blob/master/…
    • 这个问题我真的需要帮助
    • 您好@Fardin03,我仍然认为问题很简单:您确定您的 /api/login_check 与 IS_AUTHENTICATED_ANONYMOUSLY 路径匹配吗?标准正则表达式规则意味着确实如此( ^/api/login )。但我会仔细检查。例如将 ^/api/login_check 放在路径中。
    【解决方案2】:

    在 Windows 上,事情总是不同的......

    单引号不适用于数据。您必须使用双引号并使用 \"""" 转义数据中的引号。

    curl.exe -X POST -H "Content-Type: application/json" http://localhost:81/api/login_check -d "{\"username\":\"f.djawid@outlook.com\",\"password\":\"000000\"}"
    

    信息:How do I POST JSON data with cURL?(已接受答案和 cmets)

    【讨论】:

      【解决方案3】:

      所以我刚刚解决了这个问题。问题是我必须在security.yml中切换登录头和api头的位置。这次我使用邮递员测试它是否有效,我得到了一个令牌。它仍然无法在我的本地服务器上运行的原因是由于某种原因 symfony 内核没有给出任何响应,但这完全是另一个问题。

      【讨论】:

      • 我在 access_control 区域的顶部有我的,JWT 令牌效果很好。这是你做的吗? - { 路径:^/api/login,角色:IS_AUTHENTICATED_ANONYMOUSLY }
      • 我的登录防火墙规则也在api防火墙规则之前。 IE:在防火墙中,我有 dev、login、api、main。防火墙规则的顺序也很重要。
      • 这让我很困惑,但现在很清楚为什么必须先登录,然后是 api 标头
      猜你喜欢
      • 2016-01-21
      • 2018-02-24
      • 2018-12-25
      • 2017-07-13
      • 2016-09-13
      • 2020-09-09
      • 2020-05-24
      • 2020-01-31
      • 2021-12-29
      相关资源
      最近更新 更多