How to Build a JSON Authentication Endpoint
Warning: You are browsing the documentation for Symfony 3.x, which is no longer maintained.
Read the updated version of this page for Symfony 7.1 (the current stable version).
In this entry, you'll build a JSON endpoint to log in your users. When the user logs in, you can load your users from anywhere - like the database. See Security for details.
First, enable the JSON login under your firewall:
1 2 3 4 5 6 7 8 9
# app/config/security.yml
security:
# ...
firewalls:
main:
anonymous: ~
json_login:
check_path: /login
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
<!-- app/config/security.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<srv:container xmlns="http://symfony.com/schema/dic/security"
xmlns:srv="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
https://symfony.com/schema/dic/services/services-1.0.xsd">
<config>
<firewall name="main">
<anonymous/>
<json-login check-path="/login"/>
</firewall>
</config>
</srv:container>
1 2 3 4 5 6 7 8 9 10 11
// app/config/security.php
$container->loadFromExtension('security', [
'firewalls' => [
'main' => [
'anonymous' => null,
'json_login' => [
'check_path' => '/login',
],
],
],
]);
Tip
The check_path
can also be a route name (but cannot have mandatory
wildcards - e.g. /login/{foo}
where foo
has no default value).
The next step is to configure a route in your app matching this path:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
// src/AppBundle/Controller/SecurityController.php
// ...
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
class SecurityController extends Controller
{
/**
* @Route("/login", name="login")
*/
public function loginAction(Request $request)
{
$user = $this->getUser();
return $this->json([
'username' => $user->getUsername(),
'roles' => $user->getRoles(),
]);
}
}
1 2 3 4
# app/config/routing.yml
login:
path: /login
defaults: { _controller: AppBundle:Security:login }
1 2 3 4 5 6 7 8 9 10 11
<!-- app/config/routing.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing
https://symfony.com/schema/routing/routing-1.0.xsd">
<route id="login" path="/login">
<default key="_controller">AppBundle:Security:login</default>
</route>
</routes>
1 2 3 4 5 6 7 8 9 10
// app/config/routing.php
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
$routes = new RouteCollection();
$routes->add('login', new Route('/login', [
'_controller' => 'AppBundle:Security:login',
]));
return $routes;
Now, when you make a POST
request, with the header Content-Type: application/json
,
to the /login
URL with the following JSON document as the body, the security
system intercepts the request and initiates the authentication process:
1 2 3 4
{
"username": "dunglas",
"password": "MyPassword"
}
Symfony takes care of authenticating the user with the submitted username and password or triggers an error in case the authentication process fails. If the authentication is successful, the controller defined earlier will be executed.
If the JSON document has a different structure, you can specify the path to
access the username
and password
properties using the username_path
and password_path
keys (they default respectively to username
and
password
). For example, if the JSON document has the following structure:
1 2 3 4 5 6 7 8
{
"security": {
"credentials": {
"login": "dunglas",
"password": "MyPassword"
}
}
}
The security configuration should be:
1 2 3 4 5 6 7 8 9 10 11
# app/config/security.yml
security:
# ...
firewalls:
main:
anonymous: ~
json_login:
check_path: login
username_path: security.credentials.login
password_path: security.credentials.password
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
<!-- app/config/security.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<srv:container xmlns="http://symfony.com/schema/dic/security"
xmlns:srv="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
https://symfony.com/schema/dic/services/services-1.0.xsd">
<config>
<firewall name="main">
<anonymous/>
<json-login check-path="login"
username-path="security.credentials.login"
password-path="security.credentials.password"/>
</firewall>
</config>
</srv:container>
1 2 3 4 5 6 7 8 9 10 11 12 13
// app/config/security.php
$container->loadFromExtension('security', [
'firewalls' => [
'main' => [
'anonymous' => null,
'json_login' => [
'check_path' => 'login',
'username_path' => 'security.credentials.login',
'password_path' => 'security.credentials.password',
],
],
],
]);