我对后端开发很新......
使用我的API我希望能够显示用户列表,并指出他们当前是否已登录。我使用passport
和json web token
进行了基本身份验证工作
我不希望获得当前登录的用户。
我希望能够检索用户列表并查看他们是否已登录。
像这样:
var users = Users.find({});
// console.log(users) output:
{
name: 'foo'
password: ...
isLoggedIn: false
},
{
name: 'bar'
password: ...
isLoggedIn: true
},
{
name: 'baz'
password: ...
isLoggedIn: false
}
如果用户当前已登录,则 isLoggedIn将设置为true
,如果不是,则设置为false
。
我该怎么做?谢谢!
答案 0 :(得分:2)
听起来您想要做的是根据登录/注销事件更新MongoDB数据库。为此,您可以使用mongoose之类的东西来处理Node后端,以便轻松访问MongoDB中的数据库。
您可以在使用npm install mongoose
进行安装后添加mongoose,如下所示:
var mongoose = require('mongoose');
var User = mongoose.model('User');
请注意,User
对应于您为存储用户信息而创建的任何架构。
假设您有某种router
对象来处理请求,您可以为/logout
和/login
构建路由处理程序,并使用导入的mongoose User模型来检索并修改特定的用户对象如下:
// whenever user goes to '/login' (you can have, say, your 'login' button make a request to this URL
router.get('/login', function(req,res) {
// your authentication here; passport stores the currently authenticated user in req.user
var username = req.user.name; // here we assume the username is stored as 'name' as you have in your code but change this based on your schema
User.findOne({name: username}, function(err, user, data) {
if(err) res.send(err);
user.isLoggedIn = true;
user.save(function (err) {
if (err) {
console.log(err);
} else {
// redirect to some page here maybe
}
});
});
});
// whenever user goes to '/logout' (you can have a logout button make a request to this URL
router.get('/logout', function(req,res) {
// currently authenticated user is still in req.user
var username = req.user.name;
User.findOne({name: username}, function(err, user, data) {
if(err) res.send(err);
user.isLoggedIn = false;
user.save(function (err) {
if (err) {
console.log(err);
} else {
// redirect to login/register page maybe
}
});
});
});
总结一下这段代码会做什么:
根据用户访问的网址,我们的路由处理程序将根据名称(用户名)从我们的数据库中获取一个正确的唯一User对象
它会通过访问req.user
的用户名属性来实现,该属性对应于当前经过身份验证的Passport用户,对于所有用户来说也是如此
更新我们用于跟踪登录状态的字段(isLoggedIn
)
然后保存更改,之后我们更新状态以反映用户是否已登录,因此我们现在可以重定向到其他页面或显示其他内容
最后,您可以检索所有用户的列表,类似于您的代码,如下所示:
User.find({}, function(err, users, data) {
// all users from your database are in `users`
console.log(users);
});
编辑过期的会话:
因此,要跟踪过期的会话,因为您正在使用Passport,理论上需要功能来通过某种事件/回调/消息等发出信号,此时会话被视为无效。现在这很难监控,而且根据我对Passport的经验,这样的东西并没有在所有身份验证策略中实现,并且可能因开发人员使用的策略而异(例如,如果浏览器窗口关闭,请考虑基于Passports身份验证策略,或只是浏览器,它可能会立即破坏会话的cookie,我们的服务器无法知道它)。我建议检查Passport提供的所有身份验证策略,以防有更好的here。
现在,如果您想添加功能以自行跟踪用户的被动登录/注销状态,您可以使用与cookie相关的内容。同样,不一定要使用,但这里有一些方便的Express模块:cookie-parser和cookie-session。
然后,您可以使用cookie-parser
:
var express = require('express');
var cookieParser = require('cookie-parser');
var app = express();
app.use(cookieParser());
在用户通过身份验证后,您可以将此代码放在某处:
// cookies are stored here
console.log(req.cookies);
// configure your cookie
var options = {
expires: 1000 * 60 * 60, // expires after one hour
httpOnly: true
}
// Set cookie
res.cookie('session', ('user-' + req.user.name), options);
然后,在客户端检查该cookie是否在某个时间间隔内持续有效,如果它已过期Date.now() > cookie.expires
,则向/logout
发出GET请求,然后注销用户(目前仍经过身份验证)通过更新MongoDB和所有。
但是,由于这需要建立一个基本模拟过期会话的机制,我建议使用类似于超时的东西,这将更容易实现。只需注意,这有点类似于您可能遇到的某些页面上的机制,其中您会弹出一个“由于不活动而将被注销”的弹出窗口。在您的main.js
或任何客户端脚本中定义一个继续超时的函数,除非用户执行某些操作。
var inactivity = function () {
var t;
// user doing something on your page, so keep resetting time counter when events happen
document.onmousemove = resetTimer;
document.onkeypress = resetTimer;
// this is a callback function that will get called once a time-out countdown is done
function timeOut() {
// make a request to '/logout' here and logout the current user (you still will have access to req.user from Passport)
// also can redirect from back-end route handler to the login page for instance
}
// this gets called whenever an event happens, resetting the counter of sorts
function resetTimer() {
t = 0;
t = setTimeout(timeOut, 1000 * 60 ) // set this to however long you should wait to log out your user time (in milliseconds)
}
};
基本上,这种方法可以让你自己使会话自动失效,这意味着你可以更好地控制更新数据库的状态并将用户注销。
希望这有帮助!