2

我正在使用 Symfony 4“带有 Guard 的自定义身份验证系统(API 令牌示例)”带有 Guard 的自定义身份验证系统(API 令牌示例)

我想在用户从其他应用程序(即 Advance Rest 客户端)注册时生成 api 令牌,然后想使用此令牌访问其他 api,例如获取文章列表。

没有生成令牌的选项,或者我可能找不到。

这是我的代码:

配置/包/security.yaml

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

# 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
firewalls:
    dev:
        pattern: ^/(_(profiler|wdt)|css|images|js)/
        security: false
    api:
        pattern:    ^/api/
        stateless:  true
        anonymous:  false
        guard:
            authenticators:
                - App\Security\TokenAuthenticator
    main:
        pattern: ^/
        anonymous: true
        guard:
            authenticators:
                - App\Security\LoginFormAuthenticator
        logout:
            path:   app_logout

        # activate different ways to authenticate

        # http_basic: true
        # https://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate

        # form_login: true
        # https://symfony.com/doc/current/security/form_login_setup.html

# 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, roles: [ IS_AUTHENTICATED_FULLY ] }
    - { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/admin, roles: ROLE_ADMIN }
    # - { path: ^/profile, roles: ROLE_USER }

控制器/RegistrationController.php

class RegistrationController extends AbstractController{

/**
 * @Route("/register/api", name="app_register_api")
 */
public function registerApi(Request $request, UserPasswordEncoderInterface $passwordEncoder, GuardAuthenticatorHandler $guardHandler, TokenAuthenticator $authenticator){

    $user = new User();
    $form = $this->createForm(RegistrationFormType::class, $user);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
        // encode the plain password
        $user->setPassword(
            $passwordEncoder->encodePassword(
                $user,
                $form->get('plainPassword')->getData()
            )
        );

        $entityManager = $this->getDoctrine()->getManager();
        $entityManager->persist($user);
        $entityManager->flush();

        // do anything else you need here, like send an email


        $data = $guardHandler->authenticateUserAndHandleSuccess(
            $user,
            $request,
            $authenticator,
            'api' // firewall name in security.yaml
        );

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

}

}

安全/TokenAuthenticator.php

class TokenAuthenticator extends AbstractGuardAuthenticator
{
  private $em;

public function __construct(EntityManagerInterface $em)
{
    $this->em = $em;
}

/**
 * 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)
{
    return $request->headers->has('X-AUTH-TOKEN');
}

/**
 * Called on every request. Return whatever credentials you want to
 * be passed to getUser() as $credentials.
 */
public function getCredentials(Request $request)
{
    return [
        'token' => $request->headers->get('X-AUTH-TOKEN'),
    ];
}

public function getUser($credentials, UserProviderInterface $userProvider)
{
    $apiToken = $credentials['token'];

    if (null === $apiToken) {
        return;
    }

    // if a User object, checkCredentials() is called
    return $this->em->getRepository(User::class)
        ->findOneBy(['apiToken' => $apiToken]);
}

public function checkCredentials($credentials, UserInterface $user)
{
    // check credentials - e.g. make sure the password is valid
    // no credential check is needed in this case

    // return true to cause authentication success
    return true;
}

public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
    // on success, let the request continue
    return null;

}

public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
    $data = [
        'message' => strtr($exception->getMessageKey(), $exception->getMessageData())

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

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

/**
 * Called when authentication is needed, but it's not sent
 */
public function start(Request $request, AuthenticationException $authException = null)
{
    $data = [
        // you might translate this message
        'message' => 'Authentication Required'
    ];

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

public function supportsRememberMe()
{
    return false;
}
}

下一个问题是如何从文章 api 中的令牌中获取用户详细信息?

<?php

  namespace App\Controller\Rest;

  use Symfony\Component\HttpFoundation\Request;
  use Symfony\Component\HttpFoundation\Response;
  use FOS\RestBundle\Controller\FOSRestController;
  use FOS\RestBundle\Controller\Annotations as Rest;
  use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

  use App\Entity\Article;
  use App\Form\ArticleType;
  use App\Service\ArticleService;

  class ArticleController extends FOSRestController
  {
     /**
          * @var ArticleService
    */
      private $articleService;
     /**
     * ArticleController constructor.
     * @param ArticleService $articleService
     */
     public function __construct(ArticleService $articleService)
    {
      $this->articleService = $articleService;
    }

/**
* Lists all Articles.
* http://sf4.local/api/articles
* @Rest\Get("/articles")
*
* @return Response
*/
public function getArticles()
 {
    $items = $this->articlesService->getAllArticles();
    return $this->handleView($this->view($items));
 }
}
4

0 回答 0