TL;DR:
Can't succeed persisting session across multiple APIs call performed between a Backbone App and Node.js Server with Express, Express-Session and Express-Cors. Looks like session is reinitialized/lost after every call.
加长版:
我有一个在 localhost:3000 上运行的客户端 Backbone/React/Flux 应用程序在 localhost:4242 上运行的 Node.js 服务器上执行以下调用:
Http 调用
RESPONSE HEADERS
Content-Type application/json; charset=utf-8
Set-Cookie connect.sid=s%3AFeNYY5GQGvkyRvOym7DhysprePaQr7xP.BrxOPP56k9pDpxQPvwjDFaxkEYoHU%2FAEtNUIXGltqjI; Domain=http://localhost:3000; Path=/
Vary Origin
X-Powered-By Express
access-control-allow-credentials true
access-control-allow-orign http://localhost:3000
[...]
REQUEST HEADERS
Accept application/json, text/javascript, */*; q=0.01
Content-Type application/json; charset=utf-8
Cookie connect.sid=s%3AjP4iADZvRnDHbJcCE8H81Zy6TIehj9BJ.eDOTw44GcHqq8i2dslBGd43tXMQ22ENl31fRizdC8iA
Host localhost:4242
Origin http://localhost:3000
Referer http://localhost:3000/login
[...]
RESPONSE HEADERS
Content-Type application/json; charset=utf-8
Set-Cookie connect.sid=s%3ARxf91_vLMBqzB6xN-0QFIIk_-SyBP9_8.F1Mr%2BVSkYNJ6MqnzO%2BsxxfwXRinIX6th80SoukG1QBM;Domain=http://localhost:3000; Path=/
Vary Origin
X-Powered-By Express
access-control-allow-credentials true
access-control-allow-orign http://localhost:3000
[...]
REQUEST HEADERS
Accept application/json, text/javascript, */*; q=0.01
Content-Type application/json; charset=utf-8
Cookie connect.sid=s%3AjP4iADZvRnDHbJcCE8H81Zy6TIehj9BJ.eDOTw44GcHqq8i2dslBGd43tXMQ22ENl31fRizdC8iA
Host localhost:4242
Origin http://localhost:3000
Referer http://localhost:3000/login
[...]
基本上第一次调用 POST/api/session 是登录用户并尝试在 session 中存储 API token 。
第二次调用 GET/api/users 在第一次成功后立即触发,并检索用户信息。
主干方法
这是我在 Session 模型上用于登录的 Backbone 方法:
login: (options) ->
@set {user: options.user, password: options.password}
@save ['user', 'password'],
success: (data) =>
@set({authenticated: true, accessToken: data.accessToken, password: null})
options.success(data) # trigger the second call here
error: (error) =>
options.error(error)
以及在我的 UserStore 中对/api/users 的调用
users: (options) ->
@users.fetch
success: (users) =>
@users = users
options.success(users)
使用这些不同的选项(我在 Backbone.Collection/Backbone.Model 中覆盖了 Backbone.sync):
class UsersCollection extends Backbone.Collection
url: '/api/users'
model: UserModel
sync: (method, model, options) ->
options ?= {}
options.url ?= @url
options.dataType ?= 'json'
options.contentType ?= "application/json; charset=utf-8"
options.crossDomain ?= true
options.xhrFields ?= {"withCredentials": true}
super(method, model, options)
(简化版:Models 和 Collection 相同,使用 BaseCollection 和 BaseModel,我在其中覆盖了 sync() 方法)。
所以 Backbone.sync(method, model, options) 中的 Console.log(options) 正在返回:
{"url":"http://localhost:4242/api/session","dataType":"json","contentType":"application/json; charset=utf-8","crossDomain":true,"validate":true,"parse":true,"xhrFields":{"withCredentials":true}}
Node.js 设置和方法
这是我的 Node.js 路由器设置 Express:
BodyParser = require 'body-parser'
Session = require 'express-session'
Cors = require 'cors'
class Router
constructor: (express) ->
@express = express
@express.use BodyParser.json()
@express.use Cors(@corsConfig())
@express.use Session(@sessionConfig())
# Express routes are set here
# @express.post '/api/session', (request, response) => [...]
# @express.get '/api/users', (request, response) => [...]
corsConfig: ->
origin: 'http://localhost:3000'
credentials: true
sessionConfig: ->
secret: 'whatever'
cookie:
secure: false
httpOnly: false
domain: 'http://localhost:3000'
这是我的 Node.js 方法处理 POST/api/session
login: (request, response) ->
session = request.session
console.log JSON.stringify(session)
console.log request.sessionID
console.log '---------------------------------------------'
if session.accessToken
console.log 'session with token!'
response.json {accessToken: session.accessToken}
else
console.log 'performing credentialAuthentication'
user = request.body.user
password = request.body.password
@whatever.authentication
user: user
password: password
success: (accessToken) ->
request.session.accessToken = accessToken
console.log JSON.stringify(session)
console.log request.sessionID
console.log '---------------------------------------------!!!'
response.json {accessToken: accessToken}
# also tried with response.send()
还有一个处理 GET/api/users
@express.get '/api/users', (request, response) =>
console.log JSON.stringify(request.session)
console.log request.sessionID
console.log '---------------------------------------------'
[...]
Node.js 日志
这是日志:
express:router dispatching OPTIONS /api/session
express:router dispatching POST /api/session
{"cookie":{"originalMaxAge":null,"expires":null,"secure":false,"httpOnly":false,"path":"/"}}
zse18d2zrNRdEXPjFHF0gm3NkONb-_5V
---------------------------------------------
performing credentialAuthentication
{"cookie":{"originalMaxAge":null,"expires":null,"secure":false,"httpOnly":false,"path":"/"},
"accessToken":"ebab5010f9ece5ea984e4b73f9a46ef3"}
zse18d2zrNRdEXPjFHF0gm3NkONb-_5V
---------------------------------------------!!!
express:router dispatching GET /api/users
{"cookie":{"originalMaxAge":null,"expires":null,"secure":false,"httpOnly":false,"path":"/"}}
g8YXQEpt_rnWSGdh1nCKMndiI8Lt2UDq
---------------------------------------------
您可以看到 CORS 请求正常执行,我正确获取了我的 token ,然后尝试将其存储在 session 中。
但是在第二次调用中, session 没有持久化,我无法访问我在第一次调用中实际设置的变量 (accessToken)。
查看日志和两次调用的 HTTP header ,看起来 session 每次都重新初始化,因为 session ID 和每个请求都在更改 - 并且每次都发送一个 Set-Request header (其中据我所知,不应该是这种情况)。
我怀疑这种行为是由 CORS 级别的一些不连贯或缺少配置引起的,或者是由于为 session 设置的 path (Express.use(path, middleware) 和 Cookie({path: '/'}))。然而,尽管多次尝试使用不同的配置、设置和标题,我真的无法让它工作。
非常欢迎任何能够就这种行为以及我所缺少的东西向我提供启发的人 :)
谢谢!
PS:我向非 CoffeeScript 开发者道歉 ;)
最佳答案
这是答案(简单的一个):
我错误地配置了我的 Session 中间件; cookie.domain 选项导致了问题。
这是正确的配置:
sessionConfig: ->
secret: 'whatever'
cookie:
secure: false
httpOnly: false
express/session 中间件不需要/不存在此选项(不再存在?);不知道为什么我最初使用它,可能来自过时的引用(表达/cookie-parser 或 express/cors)。
关于node.js - 在 CORS 调用后,Express Session 不会持续存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33958907/
设置:狂欢ruby1.9.2高线(1.6.13)描述:我已经相当习惯在其他一些项目中使用highline,但已经有几个月没有使用它了。现在,在Ruby1.9.2上全新安装时,它似乎不允许在同一行回答提示。所以以前我会看到类似的东西:require"highline/import"ask"Whatisyourfavoritecolor?"并得到:Whatisyourfavoritecolor?|现在我看到类似的东西:Whatisyourfavoritecolor?|竖线(|)符号是我的终端光标。知道为什么会发生这种变化吗? 最佳答案
我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘
我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我需要一些关于TDD概念的帮助。假设我有以下代码defexecute(command)casecommandwhen"c"create_new_characterwhen"i"display_inventoryendenddefcreate_new_character#dostufftocreatenewcharacterenddefdisplay_inventory#dostufftodisplayinventoryend现在我不确定要为什么编写单元测试。如果我为execute方法编写单元测试,那不是几乎涵盖了我对create_new_character和display_invent
我的模型有defself.empty_building//stuffend我怎样才能对这个现有的进行rspec?,已经尝试过:describe"empty_building"dosubject{Building.new}it{shouldrespond_to:empty_building}endbutgetting:Failure/Error:it{shouldrespond_to:empty_building}expected#torespondto:empty_building 最佳答案 你有一个类方法self.empty_bu
在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList()Obt
前置步骤我们都操作完了,这篇开始介绍jenkins的集成。话不多说,看操作1、登录进入jenkins后会让你选择安装插件,选择第一个默认的就行。安装完成后设置账号密码,重新登录。2、配置JDK和Git都需要执行路径,所以需要先把执行路径找到,先进入服务器的docker容器,2.1JDK的路径root@69eef9ee86cf:/usr/bin#echo$JAVA_HOME/usr/local/openjdk-82.2Git的路径root@69eef9ee86cf:/#whichgit/usr/bin/git3、先配置JDK和Git。点击:ManageJenkins>>GlobalToolCon
说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时