Symfony 4 - JSON认证不起作用

4
我将翻译以下内容:

我正在尝试基于以下文档在Symfony中构建一个JSON身份验证机制: https://symfony.com/doc/current/security/json_login_setup.html

这是我的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

这里是我的安全控制器中的登录方法。
class SecurityController extends Controller
{
    ...
    /**
     * @Route("/login", name="login")
     * @return Response
     */
    public function login()
    {
        return new Response('Lala');
    }
    ...
}

这里是我的登录表单

<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>

以下是我发送到控制器的AJAX请求:

$('#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);
        }
    });
});

我从服务器那里收到了200状态码,但什么也没有发生。安全认证机制根本没有反应。Ajax中的成功方法也没有调用。我不知道为什么。我在互联网上搜索了很多,但关于Symfony中json认证的信息几乎没有。Symfony文档上只有简短的描述。


你是否按照文档的建议,在security.yamljson_login键中添加了username_path: security.credentials.loginpassword_path: security.credentials.password - baris1892
嘿。从我的AJAX请求中可以看出,我正在以最简单的格式发送JSON:{"username": "dunglas", "password": "MyPassword"}因此不需要指定username_pathpassword_path。文档引用:如果JSON文档具有不同的结构,则可以使用username_pathpassword_path键指定访问用户名和密码属性的路径(它们分别默认为用户名和密码)。 - Mikołaj Waśniewski
你有解决这个问题吗?也许问题出在非空的控制器上,因为这份文档明确指出控制器应该是空的:http://symfony.com/doc/current/security/json_login_setup.html我现在遇到了同样的问题,不知道该怎么继续。 - user3507003
我也遇到了同样的问题。你之所以能够得到正确的响应,是因为你的控制器返回了一个有效的对象。实际上,控制器根本不应该被调用,而应该被安全系统拦截。 - Philipp Waller
1个回答

6
我能够识别问题所在。只有当请求头设置为Content-Type: application/json时,才会发生拦截:

请在控制台中尝试以下操作:

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

在您的情况下,这应该解决问题:
$('#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);
        }
    });
});

你如何处理“记住我”部分?它也被处理了吗? - mehmetsen80
这无法使用现代 JavaScript 的 fetchaxios 库工作 :( 有任何帮助吗? - Khalid Ahmada
当您通过AJAX登录时,如何保持登录状态?在我的情况下,我可以从localhost-1成功登录到localhost-2。当我通过$.get(url)获取内容时,我再次得到401错误。使用NelmioCorsBundle启用了CORS。 - Daviz
嗨@KhalidAhmada,由于两个库都可以像上面的示例一样自定义请求头,所以身份验证应该可以正常工作。请查看此处获取fetch此处获取axios的相关信息。 - Philipp Waller
1
嗨@Daviz,这取决于您要实现哪种API类型。例如,REST API是无状态的,无法区分用户是否在线或离线。授权凭据需要随每个请求发送。但是,您可以使用登录功能生成用户特定的JWT令牌。该令牌可以限时使用,并将用于所有后续的api请求。 - Philipp Waller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接