Skip to content

JSON authentication listener docs #7081

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Dec 14, 2016
200 changes: 200 additions & 0 deletions security/json_login_setup.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
How to Build a JSON Authentication Endpoint
===========================================

In this entry, you'll build a JSON endpoint to log in your users. Of course, when the
user logs in, you can load your users from anywhere - like the database.
See :ref:`security-user-providers` for details.

First, enable the JSON login under your firewall:

.. configuration-block::

.. code-block:: yaml

# app/config/security.yml
security:
# ...

firewalls:
main:
anonymous: ~
json_login:
check_path: /login

.. code-block:: xml

<!-- 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
http://symfony.com/schema/dic/services/services-1.0.xsd">

<config>
<firewall name="main">
<anonymous />
<json-login check-path="/login" />
</firewall>
</config>
</srv:container>

.. code-block:: php

// app/config/security.php
$container->loadFromExtension('security', array(
'firewalls' => array(
'main' => array(
'anonymous' => null,
'json_login' => array(
'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).

Now, when a request is made to the ``/login`` URL, the security system initiates
the authentication process. You just need to define anywhere in your application
an empty controller associated with that URL:

.. configuration-block::

.. code-block:: php-annotations

// src/AppBundle/Controller/SecurityController.php

// ...
use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

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

.. code-block:: yaml

# app/config/routing.yml
login:
path: /login
defaults: { _controller: AppBundle:Security:login }

.. code-block:: xml

<!-- 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
http://symfony.com/schema/routing/routing-1.0.xsd">

<route id="login" path="/login">
<default key="_controller">AppBundle:Security:login</default>
</route>
</routes>

.. code-block:: php

// app/config/routing.php
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;

$collection = new RouteCollection();
$collection->add('login', new Route('/login', array(
'_controller' => 'AppBundle:Security:login',
)));

return $collection;

Don't let this empty controller confuse you. When you submit a ``POST`` request
to the ``/login`` URL with the following JSON document as body, the security
system automatically handles it and takes care of checking the submitted
username and password and authenticating the user or throwing an error:

.. code-block:: json
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some reason, this block does not render well: http://pr-7081-acxnhhi-6qmocelev2lwe.eu.platform.sh/security/json_login_setup.html

(probably because of the double colon L.149)


{
"username": "dunglas",
"password": "MyPassword"
}

If the JSON document has a different structure, you can specify the path to
access to the user 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:

.. code-block:: json

{
"security": {
"credentials": {
"login": "dunglas",
"password": "MyPassword"
}
}
}

The security configuration should be:

.. configuration-block::

.. code-block:: yaml

# app/config/security.yml
security:
# ...

firewalls:
main:
anonymous: ~
json_login:
check_path: login
username_path: security.credentials.login
password_path: security.credentials.password

.. code-block:: xml

<!-- 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
http://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>

.. code-block:: php

// app/config/security.php
$container->loadFromExtension('security', array(
'firewalls' => array(
'main' => array(
'anonymous' => null,
'json_login' => array(
'check_path' => 'login',
'username_path' => 'security.credentials.login',
'password_path' => 'security.credentials.password',
),
),
),
));