如何为passportjs使用jquery / ajax数据

如果我使用表单字段action="/login", method="post"发送一个login请求,它工作得很好。 类似于这里或这里可用的代码。

但是,如果我使用jquery/ajax发送相同的信息,那么护照似乎不起作用。 没有实际的login通过护照发生,但ajax调用给出了一个令人误解的成功消息。

以下是不工作。 虽然我得到“login成功”的消息,login并没有真正发生。

 $('#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方法,以便在成功login后在客户端执行一些有用的操作。 例如,启动socket.io

请帮忙。 我的修改代码在这里可用: my-modified-code

我试过你的代码和护照明智的作品。 我做了“本地注册”,“注销”,然后“本地login”,并成功通过身份validation,但在UI中没有任何表示。

这与你所说的302相关 – 服务器回答了302,因为你已经定义了successRedirect : '/profile' ,然后jQuery跟随了redirect,并收到了它无法parsing的HTML,因为它期望JSON。 而且,由于您没有在您的$.ajax调用中定义的.fail()callback,因此您没有看到它。

虽然可以通过手动到/profile来看到会话,但会话还是可以的。

当你使用普通的HTML表单login时,浏览器将发送一个HTTP请求,并根据响应进行操作(例如,呈现HTML页面,或者如果是302则执行redirect)。 同样的情况发生,但在不同的情况下,当你调用$.ajax – AJAX调用遵循redirect,因为它提出请求,但浏览器不。

您应该为AJAX和HTMLlogin使用单独的路由,或使用自定义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 })); 

自定义callback可能是这样的(未testing):

 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); }); 

没有人可以看出你的服务器端代码,你正在使用的护照策略。 例如,本地策略的代码片段如下所示:

 function Strategy(options, verify) { // snip this._usernameField = options.usernameField || 'username'; this._passwordField = options.passwordField || 'password'; // snip } // snip Strategy.prototype.authenticate = function(req, options) { options = options || {}; var username = lookup(req.body, this._usernameField) || lookup(req.query, this._usernameField); var password = lookup(req.body, this._passwordField) || lookup(req.query, this._passwordField); // snip 

}

您从jQuery传递的字段需要与您在服务器端configuration的方式匹配,以及该策略正在寻找什么。 在这种情况下,如果您使用本地策略而不configuration用户名和密码,则会查找要在req.body或req.query中传递的用户名和通行字段。

所以没有电子邮件将无法正常工作。 但是,您可以通过在选项对象中传入覆盖默认用户名的字段来实例化策略,例如,

 { username: 'email' } 

我以前使用过这个来通过jQuery来validation护照:

  var login = function (un, pwd) { $.ajax({ type: "POST", dataType: 'json', data: { "email": un.val(), "password": pwd.val() }, url: "/rest/login/?format=json", success: function (data) { window.location.href = '/somewhereElse' } }); } 

我怀疑你的dataType需要'json'而不是'html'

也许这是一个比埋在评论中更好的地方。 几个月前我经历过类似的事情,在这里回答我自己的问题:

Passport身份validationcallback不传递req和res

基本上我能够得到它的工作与邮政处理签名:请求,水库,旁边和内部的处理程序,你叫护照。validation期望的策略。 passport.authenticate不应该(或者至less在我的情况下不会作为)路由的处理程序

 server.post(route, function(req, res, next){ passport.authenticate('local', function(err, user) { }) }) 

我从来没有能够得到passReqToCallback选项的工作。