LexikJWTAuthenticationBundle与多个提供程序

时间:2019-07-26 17:25:32

标签: php symfony4 lexikjwtauthbundle

应用程序的第2部分-第一个用于管理员(管理面板),第二个用于API。 对于API,我想使用其他模型来检查凭据并检索令牌。 我认为可以通过指定 check_path 路由来实现,我可以在其中验证提供的数据,然后手动返回令牌。

但是似乎该应用程序没有事件到达该端点,因为我没有从响应中看到任何调试消息-仅401错误代码。 这是我的security.yml配置:

security:
    encoders:
        App\Entity\Security\AdminUser:
            algorithm: bcrypt
        Lexik\Bundle\JWTAuthenticationBundle\Security\User\JWTUser:
            algorithm: bcrypt

role_hierarchy:
    ROLE_ADMIN:       ROLE_USER
    ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
    fos_userbundle:
        id: fos_user.user_provider.username_email
    jwt:
        lexik_jwt: ~

firewalls:
    api:
        provider: jwt
        pattern:  ^/api/
        stateless: true
        anonymous: true
        guard:
            authenticators:
                - 'jwt.token.authenticator'
        json_login:
            check_path: api.v1.0.token.get
            username_path: passwordName
            success_handler: lexik_jwt_authentication.handler.authentication_success
            failure_handler: lexik_jwt_authentication.handler.authentication_failure
    dev:
        pattern: ^/(_(profiler|wdt)|css|images|js)/
        security: false
    main:
        context: 'main'
        pattern: ^/
        form_login:
            provider: fos_userbundle
            default_target_path: easyadmin
            csrf_token_generator: security.csrf.token_manager

        logout:       true
        anonymous:    true


access_control:
    - { path: ^/api/doc, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/api/v1.0/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/api,       roles: IS_AUTHENTICATED_FULLY }

这是我尝试调试的动作:

class TokenController extends AbstractController
{
/**
 * @Route("/login", name="api.v1.0.token.get", methods={"POST"})
 * @param Request $request
 */
public function obtainToken(Request $request, JWTEncoderInterface $encoder, SiteRepository $siteRepository)
  {
      dd(123); // I don`t see this message - only 401 error

  }
}

1 个答案:

答案 0 :(得分:2)

首先,我不确定您要使用 obtainToken 函数做什么,但是如果您需要以编程方式创建令牌或在返回令牌之前对其进行操作/自定义内容,我高度重视建议您先看看他们的文档,因为您将拥有实现所需功能的所有工具:

否则,捆绑包将为您处理。

现在,假设您只想使用JWT保护api,则需要将api防火墙分为两个不同的防火墙:

第一个登录,就像这样:

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

请不要忘记更新访问控制以确保您的用户可以匿名访问它:

- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }

这将允许您使用凭据来打入/ api / login_check以进行身份​​验证并获取令牌。


然后,通过定义JWT Guard身份验证器来保护其余的公共api,如下所示:

api:
  pattern: ^/api
  stateless: true
  # /!\ shouldn't be anonymous: true here
  provider: jwt
  guard:
    authenticators:
    - lexik_jwt_authentication.jwt_token_authenticator

访问控制也是如此:

- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }

如果您需要创建一个帐户,则可以定义自己的路线,并在成功后以编程方式创建令牌。


要提的其他一些事情:

  • check_path: api.v1.0.token.get:我实际上从未尝试过,但我认为您不能像这样通过其路由名称定义路径,最好直接指定该路径。
  • username_path: passwordName:在这里,您告诉捆绑包使用“ passwordName”作为用户名,听起来很奇怪。

如果您想同时为用户名和密码指定自定义标识符,则最好使用如下所示:

username_path: email # (or whatever field you use for the authentication)
password_path: password