具有RESTful身份验证的Symfony2 App,使用FOSRestBundle和FOSUserBundle

Mic*_*zov 5 php restful-authentication symfony fosuserbundle fosrestbundle

我正在为我的JS驱动的应用程序制作REST API.

在登录期间,登录表单通过AJAX提交到/rest/login我的API的url .

  • 如果登录成功,则返回204
  • 如果失败,则返回401

虽然我已经为API和应用程序本身分离了防火墙,但它们共享相同的上下文,这应该意味着,当用户对API进行身份验证时,他也会针对应用程序进行身份验证.因此,当服务器返回204时,页面将重新加载,它应该将用户重定向到应用程序,因为他现在已登录.

我试图使用check_loginFOSUserBundle的预制页面并指向/rest/login那里.

login:
    path: /rest/login
    defaults:
        _controller: FOSUserBundle:Security:check
    methods: [ POST ]
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为它总是返回重定向,无论如何.我阅读了symfony的文档,找不到如何制作自定义check_login页面.我需要的是这样的事情

use Symfony\Component\Security\Core\Exception\AuthenticationException;
use FOS\RestBundle\Controller\Annotations\View;    

class SecurityController {

    /**
     * @View(statusCode=204)
     */
    public function loginAction($username, $password) {

        /* first I need to somehow authenticate user 
           using normal authentication, that I've set up */
        ...

        /* Then I need to return 204 or throw exception,
           based on result.
           This is done using FOSRestBundle and it's
           listeners. */

        if(!$succesful) {
            throw new AuthenticationException();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我不知道该怎么做.我在任何文档中找不到任何帮助我的东西.我将感谢能够指出正确方向的任何建议.


编辑:为了进一步简化,我的目标是什么.我希望我的登录功能与普通的form_login完全相同.我只想改变它发回的响应 - 而不是重定向我想成功204和失败401.

Mic*_*zov 12

我找到了一个简单的解决方案.我只需要编写一个实现AuthenticationSuccessHandlerInterface和实现的类AuthenticationFailureHandlerInterface.

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\Http\Authentication\AuthenticationFailureHandlerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;

class AuthenticationRestHandler implements AuthenticationSuccessHandlerInterface, AuthenticationFailureHandlerInterface {

    public function onAuthenticationFailure(Request $request, AuthenticationException $exception) {
        return new Response('', Response::HTTP_UNAUTHORIZED);
    }

    public function onAuthenticationSuccess(Request $request, TokenInterface $token) {
        return new Response('', Response::HTTP_NO_CONTENT);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我将其注册为服务并配置为防火墙的处理程序.

services:
  security.authentication_rest_handler:
    class: AuthenticationRestHandler

security:
  firewalls:
    rest:
      pattern: ^rest
      context: app
      form_login:
        check_path: /rest/login
        provider: fos_userbundle
        failure_handler: inspireon.security.authentication_rest_handler
        success_handler: inspireon.security.authentication_rest_handler
        username_parameter: login
        password_parameter: password
Run Code Online (Sandbox Code Playgroud)

问题解决了,无需复杂的身份验证提供程序:-)