New in Symfony 3.3: JSON authentication

Symfony 3.2 was released just a few days ago, but we've already started working on Symfony 3.3, which will be released at the end of May 2017. This is the first article of the "New in Symfony 3.3" series where we'll showcase the most relevant new features of this version.


Contributed by
Kévin Dunglas
in #18952.

The Symfony Security component provides out-of-the-box support for several authentication mechanisms, such as form logins and HTTP. In Symfony 3.3 we added a new mechanism based on JSON. It's similar to the traditional form login, but it takes a JSON document as entry and is convenient for APIs, especially used in combination with JWT.

In practice, first you need to add the json_login option to your firewall and define the URL used to log in users:

1
2
3
4
5
6
7
8
# app/config/security.yml
security:
    # ...
    firewalls:
        main:
            # ...
            json_login:
                check_path: /login

Then, create an empty controller associated with that URL. The controller must be empty because Symfony intercepts and handles this request (it checks the credentials, authenticates the user, throws an error if needed, etc.):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// src/AppBundle/Controller/SecurityController.php
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;

class SecurityController extends Controller
{
    /**
     * @Route("/login", name="login")
     */
    public function loginAction(Request $request)
    {
    }
}

And that's all. You can now log in users sending a JSON document like the following to the /login URL:

1
{ "username": "dunglas", "password": "foo1234" }

You can read the new How to Build a JSON Authentication Endpoint article for more details and to learn about its customization options.

Comments

Really great feature ! :)
It's important that the route can be matched so it doesn't throw a 404 before the security kicks in, so simply defining the route in your routing.yml is sufficient enough if you prefer that.
About "check_path: /login" :
Is it mandatory to create a controller where we specify explicitly that "/login" is the proper route?
IIRC, if you have a controller, it's better to use the route_name instead of a pattern, else you can use the pattern without controller.
Should be tested, but this is what I remember about form_login, so why would it be different for json_login ?
@Iltar yes, that's possible too (as explained in the linked article).

@Alex yes, you can also use a route name. And you can also change the structure of the JSON document sent to that URL. Everything is explained in the linked article.
@Javier So using the controller is totally optional in your example, as you don't use route name but a route pattern that is handled directly by the Security component right before resolving it as a controller :)
@Alex the controller is useless, but the routing annotation being on it is not, as it defines the route (which is necessary to avoid getting a 404 from the routing component before reaching the security component).
So if you don't want to define an empty controller, you need to use YAML or XML for the route.
great!
Awesome!
Ohh, muy bueno esto. Me gusta y creo que es muy util este otro tipo de autenticación. Ya quiero tenerlo!!
Realy good this. I think this type of authentication is very useful. I want Symfony 3.3 ya!
Really nice feature, thank you guys!
Really great feature! Keep up the good work :)
Loving the direction Symfony keeps going - forward. Great team, awesome features, kudos and thanks.
Really great feature excited for release :)
Great Feature. Thanks! Is the article "How to Build a JSON Authentication Endpoint" already available? Currently, the link leads to the PR.
@Hannes the article has been merged, so it will be available soon.
How do you use this with JWT? I couldn't see anything in examples or in the docs?

Comments are closed.

To ensure that comments stay relevant, they are closed for old posts.