如果我使用表单字段 action="/login", method="post" 发送登录请求,它就可以正常工作。类似于可用的代码 herehere

但是,如果相反,如果我使用 jquery/ajax 发送相同的信息,那么 Passport 似乎不起作用。没有通过 Passport 进行实际登录,但 ajax 调用给出了误导性的成功消息。

下面的不起作用。虽然我收到“登录成功”消息,但登录并没有真正发生。

$('#login_button').click(function () {

    var email = $('#email').val();
    var password = $('#password').val();
    alert ('email/pass:' + email + ", " + password);

    $.ajax({
        type: "POST",
        url: "/login",
        data: { email: email , password: password },
        dataType: 'html'
    })
            .done(function () {
                console.log("http request succeeded");
                alert("login success");
            });
});

我需要使用 ajax 方法,以便在成功登录后我可以在客户端做一些有用的事情。例如。启动 socket.io

请帮忙。我修改后的代码可以在这里找到:my-modified-code

最佳答案

我试过你的代码和 Passport-wise 它的工作原理。我做了“本地注册”,“注销”,然后“本地登录”并成功通过身份验证,但在 UI 中没有任何指示。

这与您正在谈论的 302 相关 - 服务器回复 302 因为您已经定义了 successRedirect : '/profile' ,然后 jQuery 跟随重定向并接收到它无法解析的 HTML,因为它需要 JSON。而且由于您没有在 .fail() 调用中定义 $.ajax 回调,因此您看不到它。

session 很好,但可以通过手动转到 /profile 来查看。

当您使用常规 HTML 表单登录时,浏览器将发送单个 HTTP 请求并根据响应执行操作(例如呈现 HTML 页面,或者如果是 302 则执行重定向)。当您调用 $.ajax 时会发生同样的情况,但在不同的上下文中 - AJAX 调用遵循重定向,因为它发出了请求,但浏览器没有。

您应该为 AJAX 和 HTML 登录使用单独的路由,或者使用 custom callback 并根据 req.accepts() 确定要返回的内容。

单独的路线可以是例如。

// AJAX logins to this URL, redirect on client side using
// window.location.href if login succeeds
app.post('/login/ajax', passport.authenticate('local-login'));

// HTTP login form send to this URL
app.post('/login', passport.authenticate('local-login', {
  successRedirect : '/profile',
  failureRedirect : '/login',
  failureFlash : true
}));

自定义回调可能是这样的(未测试):
app.post('/login', function(req, res, next) {
  passport.authenticate('local-login', function(err, user, info) {
    switch (req.accepts('html', 'json')) {
      case 'html':
        if (err) { return next(err); }
        if (!user) { return res.redirect('/login'); }
        req.logIn(user, function(err) {
          if (err) { return next(err); }
          return res.redirect('/profile');
        });
        break;
      case 'json':
        if (err)  { return next(err); }
        if (!user) { return res.status(401).send({"ok": false}); }
        req.logIn(user, function(err) {
          if (err) { return res.status(401).send({"ok": false}); }
          return res.send({"ok": true});
        });
        break;
      default:
        res.status(406).send();
    }
  })(req, res, next);
});

关于javascript - 如何为passportjs使用jquery/ajax数据,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26019995/

10-12 12:27
查看更多