草庐IT

javascript - Node.js & Express session 问题

coder 2023-05-29 原文

我遇到了 session 问题,有时我只是设置了 session 变量 在下一页请求中未定义。我通常必须通过流程 再次正确设置变量。

我可以确认我没有尝试将 session 变量设置为未定义;它们具有合法的值(value)。

在我的应用程序中,用户从/twitter/connect/移动到/twitter/callback/。前者从 twitter 中检索一些 oauth 数据,后者将用户登录到 twitter。

/twitter/connect/很简单:

app.get('/twitter/connect/?', function(req, res){
    consumer().getOAuthRequestToken(function(error, oauthToken, oauthTokenSecret, results){
        if (error){
            // error handling here
        } else {
            req.session.oauthRequestToken = oauthToken;
            req.session.oauthRequestTokenSecret = oauthTokenSecret;

            // if I console.log the two session variables above
            // they have the proper values.

            res.redirect("https://twitter.com/oauth/authorize?oauth_token="+req.session.oauthRequestToken);      
        }
    });
});

之后,twitter 将它们发送回/twitter/callback/:

app.get('/twitter/callback/?', function(req, res){
    console.log(req.session.oauthRequestToken);
    console.log(req.session.oauthRequestTokenSecret);

    // more often than not, the two variables above are
    // undefined.  but not always.  usually on the first
    // pass, never on the second.
});

我不知道发生了什么,我可以确认 session 变量设置正确,它们只是在页面请求之间没有保持它们的值,而只是第一次。

这就是我创建服务器的方式:

app.configure('development', function(){
    app.use(express.cookieParser());
    app.use(express.session({ secret:'yodawgyo' }));
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
    app.use(express.logger());
    app.use(express.static(__dirname + '/public'));
    app.set('view engine', 'ejs');
    app.set('view options', {
        open: '{{',
        close: '}}'
    });
});

我现在只有一个开发环境。我已经安装了 Node 0.5.0-pre,但在 0.4.1 上也看到了这个问题。我正在使用 express 2.3.2。

非常感谢任何帮助。

最佳答案

在 Connect 的 session 中,任何处理程序都可以设置 req.session.anything任何值,当您的处理程序调用 end() 时,Connect 将存储该值.如果同时有多个请求在进行,这是很危险的;当他们完成时,一个 session 值将破坏另一个 session 值。这就是拥有如此简单的 session API 的结果。 (或直接查看 session source),它不支持原子地获取和设置 session 属性。

解决方法是尽量为 session 中间件提供尽可能少的请求。以下是一些提示:

  1. 把你的express.static session 中间件上方的处理程序。
  2. 如果您无法上移一些不需要 session 的处理程序,您还可以将 session 中间件配置为忽略任何不使用 req.session 的路径通过说express.session.ignore.push('/individual/path') .
  3. 如果任何处理程序不写入 session (也许它只从 session 中读取),设置 req.session = null;在调用 res.end(); 之前.然后它不会被重新保存。

如果一次只有一个请求对 session 进行读取-修改-写入,则破坏的可能性将较小。我希望将来Connect会有更精准的 session 中间件,当然API会比我们现在的更复杂。

关于javascript - Node.js & Express session 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5883821/

有关javascript - Node.js & Express session 问题的更多相关文章

  1. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  2. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  3. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  4. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  5. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  6. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  7. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  8. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  9. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  10. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

随机推荐