当用户登录时,会为他创建一个 session ,但如果他转到另一台计算机并登录,则会为他的帐户创建第二个 session 。我想做到这一点,以便用户不能超过一个有效 session 。有没有办法通过user.steamId把session存在redis中,这样他的第一个session就失效了?
任何帮助都将非常感谢!
应用程序.js
var express = require('express'),
http = require('http');
var app = express();
var cookie = require('cookie');
var server = http.createServer(app);
var io = require('socket.io').listen(server);
var redis = require('redis');
var client = redis.createClient();
var session = require('express-session');
var redisStore = require('connect-redis')(session);
io.set('transports', ['websocket']);
var path = require('path');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var passport = require('passport');
const fs = require('fs');
require('./config/passport')(passport);
var sessionMiddleware = session({
store:new redisStore({host:'localhost',port:6379,client:client}),
secret:'secretTextchange',
saveUninitialized:false,
resave:false
});
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(sessionMiddleware);
app.use(passport.initialize());
app.use(passport.session());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
require('./routes/routes')(app,passport,client);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
io.use(function(socket, next) {
sessionMiddleware(socket.request, {}, next);
});
io.sockets.on('connection', function (socket) {
console.log("verified");
socket.on('message',function(msg){
io.sockets.emit('rmessage', {
name:socket.request.session.passport.user.name,
avatarUrl:socket.request.session.passport.user.avatarUrl,
message:msg
});
});
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
server.listen(3000);
module.exports = app;
Passport .js
var OpenIDStrategy = require('passport-openid').Strategy;
var auth = require('./auth');
var steam = require('./steam');
var s = new steam({
apiKey: auth.Steam.apiKey,
format:'json'
})
module.exports = function(passport){
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
done(null,user);
});
var SteamStrategy = new OpenIDStrategy({
// OpenID provider configuration
providerURL: auth.Steam.providerUrl,
stateless: auth.Steam.stateless,
// How the OpenID provider should return the client to us
returnURL: auth.Steam.returnUrl,
realm: auth.Steam.realm,
},
function(identifier, done) {
process.nextTick(function () {
console.log("passport-"+identifier);
s.getPlayerSummaries({
steamids:identifier.match(/\d+$/)[0],
callback:function(err,data){
var user = {
steamid:identifier.match(/\d+$/)[0],
avatarUrl: data.response.players[0].avatar,
name:data.response.players[0].personaname
};
return done(null, user);
}
});
// In case of an error, we invoke done(err).
// If we cannot find or don't like the login attempt, we invoke
// done(null, false).
// If everything went fine, we invoke done(null, user).
});
});
passport.use(SteamStrategy);
}
路由.js
module.exports = function(app,passport,client){
app.get('/', function (req,res) {
res.render('index.ejs',{
user: req.user,
title:"yo"});
});
app.get('/auth',passport.authenticate('openid'));
app.get('/auth/return',passport.authenticate('openid'),function(req,res){
if (req.user) {
res.redirect('/');
} else {
res.redirect('/');
}
});
}
最佳答案
你能用这个吗:https://www.npmjs.com/package/redis-sessions ?
有一个名为 soid 的方法,它可以获取单个 ID 的所有 session 。您可以在用户登录时查询他们的 ID。然后从该 ID 获取所有 session 。如果 soid 返回空,您可以安全地假设用户没有 session 。如果它返回时里面有东西,那么用户就有了 session 。
这是我目前最好的尝试。
祝你好运。
关于javascript - Session Node.js + Passport.js + Redis,通过user.id存储 session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35076481/
我怎样才能完成http://php.net/manual/en/function.call-user-func-array.php在ruby中?所以我可以这样做:classAppdeffoo(a,b)putsa+benddefbarargs=[1,2]App.send(:foo,args)#doesn'tworkApp.send(:foo,args[0],args[1])#doeswork,butdoesnotscaleendend 最佳答案 尝试分解数组App.send(:foo,*args)
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
使用rails4,ruby2。我在rails配置中为我的cookiesession设置了30分钟的超时时间。问题是,如果我转到表单,让session超时,然后提交表单,我会收到此ActionController::InvalidAuthenticityToken错误。如何在Rails中优雅地处理这个错误?比如说,重定向到登录屏幕? 最佳答案 在您的ApplicationController:rescue_fromActionController::InvalidAuthenticityTokendoredirect_tosome_p
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我去了这个website查看Rails5.0.0和Rails5.1.1之间的区别为什么5.1.1不再包含:config/initializers/session_store.rb?谢谢 最佳答案 这是删除它的提交:Setupdefaultsessionstoreinternally,nolongerthroughanapplicationinitializer总而言之,新应用没有该初始化器,session存储默认设置为cookie存储。即与在该初始值设定项的生成版本中指定的值相同。 关于
因此,当我遵循MichaelHartl的RubyonRails教程时,我注意到在用户表中,我们为:email属性添加了一个唯一索引,以提高find的效率方法,因此它不会逐行搜索。到目前为止,我们一直在根据情况使用find_by_email和find_by_id进行搜索。然而,我们从未为:id属性设置索引。:id是否自动索引,因为它在默认情况下是唯一的并且本质上是顺序的?或者情况并非如此,我应该为:id搜索添加索引吗? 最佳答案 大多数数据库(包括sqlite,这是RoR中的默认数据库)会自动索引主键,对于RailsMigration
Devise是一个Ruby库,它为我提供了这个User类:classUser当写入:confirmable时,注册时会发送一封确认邮件。上周我不得不批量创建300个用户,所以我在恢复之前注释掉了:confirmable几分钟。现在我正在为用户批量创建创建一个UI,因此我需要即时添加/删除:confirmable。(我也可以直接修改Devise的源码,但我宁愿不去调和它)问题:如何即时添加/删除:confirmable? 最佳答案 WayneConrad的解决方案:user=User.newuser.skip_confirmation
我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“