From 68bd9a557e83a176df22bac9646fa83091339476 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 25 Oct 2016 13:23:40 +0200 Subject: [PATCH 1/9] JSON authentication listener docs --- security/json_login_setup.rst | 168 ++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 security/json_login_setup.rst diff --git a/security/json_login_setup.rst b/security/json_login_setup.rst new file mode 100644 index 00000000000..7a096d64b5d --- /dev/null +++ b/security/json_login_setup.rst @@ -0,0 +1,168 @@ +How to Build a JSON Authentication Endpoint +=========================================== + +.. tip:: + + If you are storing users in some sort of a database, then you should consider + using `FOSUserBundle`_, which helps you build your ``User`` object and gives + you many routes and controllers for common tasks like login, registration and + forgot password. + +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 form login under your firewall: + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/security.yml + security: + # ... + + firewalls: + main: + anonymous: ~ + json_login: + check_path: login + username_path: user.login + password_path: user.password + + .. code-block:: xml + + + + + + + + + + + + + + .. 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' => 'user.login', + 'password_path' => 'user.password', + ), + ), + ), + )); + +.. tip:: + + The ``check_path`` can also be route names (but cannot have mandatory wildcards - e.g. + ``/login/{foo}`` where ``foo`` has no default value). + +Create a new ``SecurityController`` inside a bundle:: + + // src/AppBundle/Controller/SecurityController.php + namespace AppBundle\Controller; + + use Symfony\Bundle\FrameworkBundle\Controller\Controller; + + class SecurityController extends Controller + { + } + +Next, configure the route that you earlier used under your ``json_login`` +configuration (``login``): + +.. 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 + + + + + + + AppBundle:Security:login + + + + .. 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; + +Great! + +Don't let this controller confuse you. As you'll see in a moment, when the +user submits the form, the security system automatically handles the form +submission for you. If the user submits an invalid username or password, +this controller reads the form submission error from the security system, +so that it can be displayed back to the user. + +In other words the security system itself takes care of checking the submitted +username and password and authenticating the user. + +And that's it! When you submit a ``POST`` request to the ``/login`` URL with +the following JSON document as body, the security system will automatically +check the user's credentials and either authenticate the user or throw an error:: + +.. code-block:: json + + { + "user": { + "login": "dunglas", + "password": "MyPassword" + } + } + +You can specify the path to access to the user and password in the JSON document +using the ``username_path`` and the ``password_path`` keys. They default respectively +to ``username`` and ``password``. + +.. _`FOSUserBundle`: https://github.com/FriendsOfSymfony/FOSUserBundle From 0961128f851963e8e82c28edb02917a046299684 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 25 Oct 2016 15:01:41 +0200 Subject: [PATCH 2/9] Show the simple example first and then explain the complex use case --- security/json_login_setup.rst | 85 ++++++++++++++++++++++++++++++----- 1 file changed, 73 insertions(+), 12 deletions(-) diff --git a/security/json_login_setup.rst b/security/json_login_setup.rst index 7a096d64b5d..676438577f3 100644 --- a/security/json_login_setup.rst +++ b/security/json_login_setup.rst @@ -26,9 +26,7 @@ First, enable form login under your firewall: main: anonymous: ~ json_login: - check_path: login - username_path: user.login - password_path: user.password + check_path: login .. code-block:: xml @@ -43,7 +41,7 @@ First, enable form login under your firewall: - + @@ -57,8 +55,6 @@ First, enable form login under your firewall: 'anonymous' => null, 'json_login' => array( 'check_path' => 'login', - 'username_path' => 'user.login', - 'password_path' => 'user.password', ), ), ), @@ -155,14 +151,79 @@ check the user's credentials and either authenticate the user or throw an error: .. code-block:: json { - "user": { - "login": "dunglas", - "password": "MyPassword" + "login": "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" + } } } -You can specify the path to access to the user and password in the JSON document -using the ``username_path`` and the ``password_path`` keys. They default respectively -to ``username`` and ``password``. +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 + + + + + + + + + + + + + + .. 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', + ), + ), + ), + )); .. _`FOSUserBundle`: https://github.com/FriendsOfSymfony/FOSUserBundle From 6ff24dae4dbff09980ef30ab25d5a18fefdfed13 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 25 Oct 2016 15:54:16 +0200 Subject: [PATCH 3/9] Fixed the JSON format --- security/json_login_setup.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/security/json_login_setup.rst b/security/json_login_setup.rst index 676438577f3..1ff8825ec99 100644 --- a/security/json_login_setup.rst +++ b/security/json_login_setup.rst @@ -164,8 +164,8 @@ For example, if the JSON document has the following structure: .. code-block:: json { - "security": - "credentials": { + "security" { + "credentials" { "login": "dunglas", "password": "MyPassword" } From d2dd895dc273d267505c52d1a0c83374942e6ced Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 25 Oct 2016 15:55:38 +0200 Subject: [PATCH 4/9] Fixed the JSON format (this time for real) --- security/json_login_setup.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/security/json_login_setup.rst b/security/json_login_setup.rst index 1ff8825ec99..45f43cd78ad 100644 --- a/security/json_login_setup.rst +++ b/security/json_login_setup.rst @@ -164,8 +164,8 @@ For example, if the JSON document has the following structure: .. code-block:: json { - "security" { - "credentials" { + "security": { + "credentials": { "login": "dunglas", "password": "MyPassword" } From ab5259bc4fb8ed34c4d07c76d77c3919ae250a3b Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 5 Dec 2016 11:43:06 +0100 Subject: [PATCH 5/9] Removed a tip which is not too relevant for the article --- security/json_login_setup.rst | 7 ------- 1 file changed, 7 deletions(-) diff --git a/security/json_login_setup.rst b/security/json_login_setup.rst index 45f43cd78ad..97a0e8798f0 100644 --- a/security/json_login_setup.rst +++ b/security/json_login_setup.rst @@ -1,13 +1,6 @@ How to Build a JSON Authentication Endpoint =========================================== -.. tip:: - - If you are storing users in some sort of a database, then you should consider - using `FOSUserBundle`_, which helps you build your ``User`` object and gives - you many routes and controllers for common tasks like login, registration and - forgot password. - 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. From 6d018f6c1f39c29373a08cf4120a5248052fac72 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 5 Dec 2016 11:43:35 +0100 Subject: [PATCH 6/9] Fixed a syntax error --- security/json_login_setup.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/json_login_setup.rst b/security/json_login_setup.rst index 97a0e8798f0..436229bfd4c 100644 --- a/security/json_login_setup.rst +++ b/security/json_login_setup.rst @@ -139,7 +139,7 @@ username and password and authenticating the user. And that's it! When you submit a ``POST`` request to the ``/login`` URL with the following JSON document as body, the security system will automatically -check the user's credentials and either authenticate the user or throw an error:: +check the user's credentials and either authenticate the user or throw an error: .. code-block:: json From 820f28ef88d7b7791d0d207fe97fdf6a17603d25 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 5 Dec 2016 11:44:49 +0100 Subject: [PATCH 7/9] Fixed the name of the "username" property --- security/json_login_setup.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/json_login_setup.rst b/security/json_login_setup.rst index 436229bfd4c..636a3a8866f 100644 --- a/security/json_login_setup.rst +++ b/security/json_login_setup.rst @@ -144,7 +144,7 @@ check the user's credentials and either authenticate the user or throw an error: .. code-block:: json { - "login": "dunglas", + "username": "dunglas", "password": "MyPassword" } From 16ae3f60ac59f0bceb5cc2b24b3cf99073ca68fe Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 5 Dec 2016 11:54:14 +0100 Subject: [PATCH 8/9] Reworded and simplified the article --- security/json_login_setup.rst | 46 +++++++++-------------------------- 1 file changed, 12 insertions(+), 34 deletions(-) diff --git a/security/json_login_setup.rst b/security/json_login_setup.rst index 636a3a8866f..1a9c9446a12 100644 --- a/security/json_login_setup.rst +++ b/security/json_login_setup.rst @@ -5,7 +5,7 @@ In this entry, you'll build a JSON endpoint to log in your users. Of course, whe user logs in, you can load your users from anywhere - like the database. See :ref:`security-user-providers` for details. -First, enable form login under your firewall: +First, enable the JSON login under your firewall: .. configuration-block:: @@ -19,7 +19,7 @@ First, enable form login under your firewall: main: anonymous: ~ json_login: - check_path: login + check_path: /login .. code-block:: xml @@ -34,7 +34,7 @@ First, enable form login under your firewall: - + @@ -47,7 +47,7 @@ First, enable form login under your firewall: 'main' => array( 'anonymous' => null, 'json_login' => array( - 'check_path' => 'login', + 'check_path' => '/login', ), ), ), @@ -55,22 +55,12 @@ First, enable form login under your firewall: .. tip:: - The ``check_path`` can also be route names (but cannot have mandatory wildcards - e.g. + The ``check_path`` can also be a route name (but cannot have mandatory wildcards - e.g. ``/login/{foo}`` where ``foo`` has no default value). -Create a new ``SecurityController`` inside a bundle:: - - // src/AppBundle/Controller/SecurityController.php - namespace AppBundle\Controller; - - use Symfony\Bundle\FrameworkBundle\Controller\Controller; - - class SecurityController extends Controller - { - } - -Next, configure the route that you earlier used under your ``json_login`` -configuration (``login``): +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:: @@ -126,20 +116,10 @@ configuration (``login``): return $collection; -Great! - -Don't let this controller confuse you. As you'll see in a moment, when the -user submits the form, the security system automatically handles the form -submission for you. If the user submits an invalid username or password, -this controller reads the form submission error from the security system, -so that it can be displayed back to the user. - -In other words the security system itself takes care of checking the submitted -username and password and authenticating the user. - -And that's it! When you submit a ``POST`` request to the ``/login`` URL with -the following JSON document as body, the security system will automatically -check the user's credentials and either authenticate the user or throw an error: +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 @@ -218,5 +198,3 @@ The security configuration should be: ), ), )); - -.. _`FOSUserBundle`: https://github.com/FriendsOfSymfony/FOSUserBundle From b192ab30858fa510302f453e96a7bc615f00af71 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 5 Dec 2016 12:12:04 +0100 Subject: [PATCH 9/9] Fixed a syntax issue --- security/json_login_setup.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/json_login_setup.rst b/security/json_login_setup.rst index 1a9c9446a12..e9b69ac5305 100644 --- a/security/json_login_setup.rst +++ b/security/json_login_setup.rst @@ -60,7 +60,7 @@ First, enable the JSON login under your firewall: 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:: +an empty controller associated with that URL: .. configuration-block::