Symfony JSON登录-会话与令牌

ih99xse1  于 2022-11-16  发布在  其他
关注(0)|答案(1)|浏览(178)

我正在学习如何使用带有JSON登录的Symfony安全捆绑包。
因此我一直在遵循官方指南:https://symfony.com/doc/current/security.html#json-login
有趣的是,在通过身份验证后,我根本不需要发送生成的令牌,它似乎通过Session-Cookie记住了我。

$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');

作为一个初学者,我有以下问题:

  • 假设您使用REST API进行身份验证,这是一个合理的行为吗?
  • 如果我使用令牌,什么是可接受的创建方式?我可以只提供UID吗?
zzwlnbp8

zzwlnbp81#

对于令牌身份验证,您可以创建一个自定义的身份验证器。否则Symfony使用会话身份验证。这取决于前端的外观。您有办法在前端保存和重用会话吗?如果没有办法,您应该使用基于令牌的身份验证。
为了创建令牌,您可以为注册创建一个路由。这应该对匿名用户可用。这里是凭据(例如电子邮件和密码)。然后您创建一个令牌(最好是UUID)并将其保存在用户表中。最后,您在响应中发送回令牌。对于其他请求,您必须在报头中发送此令牌。然后,Symfony自动接管身份验证。
根据文档,首先创建一个验证器类。(https://symfony.com/doc/current/security/custom_authenticator.html

// src/Security/ApiKeyAuthenticator.php
namespace App\Security;

use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;

class ApiKeyAuthenticator extends AbstractAuthenticator
{
    /**
     * Called on every request to decide if this authenticator should be
     * used for the request. Returning `false` will cause this authenticator
     * to be skipped.
     */
    public function supports(Request $request): ?bool
    {
        return $request->headers->has('X-AUTH-TOKEN');
    }

    public function authenticate(Request $request): Passport
    {
        $apiToken = $request->headers->get('X-AUTH-TOKEN');
        if (null === $apiToken) {
            // The token header was empty, authentication fails with HTTP Status
            // Code 401 "Unauthorized"
            throw new CustomUserMessageAuthenticationException('No API token provided');
        }

        return new SelfValidatingPassport(new UserBadge($apiToken));
    }

    public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
    {
        // on success, let the request continue
        return null;
    }

    public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
    {
        $data = [
            // you may want to customize or obfuscate the message first
            'message' => strtr($exception->getMessageKey(), $exception->getMessageData())

            // or to translate this message
            // $this->translator->trans($exception->getMessageKey(), $exception->getMessageData())
        ];

        return new JsonResponse($data, Response::HTTP_UNAUTHORIZED);
    }
}

然后您必须在配置中注册它。

# config/packages/security.yaml
security:

    # ...
    firewalls:
        main:
            custom_authenticators:
                - App\Security\ApiKeyAuthenticator

相关问题