php - 具有多个提供商的 LexikJWTAuthenticationBundle

标签 php symfony4 lexikjwtauthbundle

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

但应用程序似乎没有事件转到此端点,因为我没有从响应中看到任何调试消息 - 只有 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

  }
}

最佳答案

首先,我不确定您要使用 obtainToken 函数做什么,但是如果您需要以编程方式创建 token 或在返回 token 之前操作/自定义其内容,我非常建议您先查看他们的文档,因为您将拥有实现您想要做的事情的所有工具:

否则, bundle 将为您处理。

现在,假设您只想使用 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 以验证并获取您的 token 。


然后,通过定义 JWT 守卫身份验证器来保护其余的公共(public) 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 }

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


还有一些事情要提:

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

如果你想为用户名和密码指定自定义标识符,你最好使用这样的东西:

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

关于php - 具有多个提供商的 LexikJWTAuthenticationBundle,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57224589/

相关文章:

php - 如何将域名后面的所有内容都变成一个字符串

doctrine-orm - Symfony 4 Doctrine 2 自定义 NamingStrategy 如何

jwt - Symfony 4:无法找到路径 "/api/login_check"的 Controller 。路由配置错误

mongodb - 如何为 Lexik JWT 身份验证实现自定义用户提供程序?

php - 错误系统库 :fopen:No such process

php - Wordpress - 在 jQuery 中获取自定义字段值

php fwrite() 没有完成将字符串数据写入文件,为什么?

javascript - 阻止人们从外部访问 HTML 表单

php - Symfony4 错误加载类自定义文件夹 "Expected to find class... but it was not found"

php - Symfony 4,find() 一个实体