4

I am trying to build a json authentication mechanism in Symfony basing on this docs: https://symfony.com/doc/current/security/json_login_setup.html

Here is my security.yaml

security:
encoders:
    App\Entity\User:
        algorithm: bcrypt
providers:
    user_provider:
      entity:
        class: App\Entity\User
        property: username
firewalls:
    dev:
      pattern: ^/(_(profiler|wdt)|css|images|js)/
      security: false
    main:
      anonymous: ~
      json_login:
        check_path: login
      provider: user_provider
      logout:
        path: logout

Here is my method login in my security controller

class SecurityController extends Controller
{
    ...
    /**
     * @Route("/login", name="login")
     * @return Response
     */
    public function login()
    {
        return new Response('Lala');
    }
    ...
}

And here is my login form

<form class="form" id="login-nav">
<div class="form-group">
    <label class="sr-only" for="username">Login</label>
    <input id="username" class="form-control" placeholder="Login" required
           name="_username">
</div>
<div class="form-group">
    <label class="sr-only" for="password">Password</label>
    <input type="password" class="form-control" id="password" placeholder="Hasło" required
           name="_password">
    <div class="help-block text-right">
        <a href="">Forgot password?</a>
    </div>
</div>
<div class="form-group">
    <a id="login-submit" class="btn btn-primary btn-block">Sign in</a>
</div>
<div class="checkbox">
    <label>
        <input type="checkbox"> Remember me
    </label>
</div>

And below you can see my AJAX request which I am sending to controller

$('#login-submit').click(function() {
    let username = $('#username').val();
    let password = $('#password').val();
    let data = JSON.stringify({username: username, password: password});
    $.ajax({
        url: '/login',
        type: 'POST',
        dataType: 'json',
        data: data,
        success: function (data, status) {
            console.log("DATA", data);
        }
    });
});

I am receiving 200 status from server but nothing happens. The security authentication mechanism is not reacting at all. And success method in ajax is not invoking. I don't know why. I was searching over the Internet a lot but there is almost no information about json authentication in Symfony. There is only a brief description on Symfony docs.

4
  • Did you add username_path: security.credentials.login and password_path: security.credentials.password to your security.yaml in key json_login (like the documentation advises)? Commented Dec 26, 2017 at 11:08
  • Hey. As you can see from my AJAX request I am sending a JSON in the simplest format: {"username": "dunglas", "password": "MyPassword"} so there is no need to specify a username_path and password_path Quote from documentation: 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). Commented Dec 26, 2017 at 12:28
  • Have you found a solution on this? Maybe the Problem is the not empty controller, as this doc states explicitly that the controller should be empty symfony.com/doc/current/security/json_login_setup.html I am having the same problem right now and dont know how to continue. Commented Jan 30, 2018 at 6:38
  • I am facing the same issue. You getting a proper response because your controller is returning a valid object. The controller should not be called at all, but intercepted by the security system. Commented Mar 2, 2018 at 13:35

1 Answer 1

6

I was able to identify the issue. The interception only happens if the request header is set to Content-Type: application/json:

Try this in your console:

curl -X POST -H "Content-Type: application/json" http://localhost:8000/login_check -d '{"username":"philipp","password":"test"}'

In your case, this should solve the problem:

$('#login-submit').click(function() {
    let username = $('#username').val();
    let password = $('#password').val();
    let data = JSON.stringify({username: username, password: password});
    $.ajax({
        url: '/login',
        type: 'POST',
        contentType: "application/json",
        dataType: 'json',
        data: data,
        success: function (data, status) {
            console.log("DATA", data);
        }
    });
});
Sign up to request clarification or add additional context in comments.

5 Comments

How do you handle the remember me section? Is it handled as well?
This not working with fetchor axios libraries using modern javascript :( there is any help ?
When you logged in via AJAX how can you stay logged in? In my case in log in successfuly from localhost-1 to localhost-2. When i get content via $.get(url) then i get a 401 again. CORS is enabled with NelmioCorsBundle.
Hi @KhalidAhmada, since both libraries can customize the request header as in the example above, the authentication should work. Please check this for fetch and this for axios.
Hi @Daviz, it depends on which API type you want to implement. A REST API e.g. is stateless and can not distinguish whether a user is online or offline. The authorization credentials need to send with every request. But you can use the login function to generate user specific JWT token. This token can be time limited and will be used for all further api requests.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.