Express session cookie 在 CORS 调用后不持久存在
Express session cookie not persisting after CORS calls
我正在设置 Node.JS 服务器,使用 Express,运行 在端口 localhost:3005 上。我在 AngularJS、运行 端口 localhost:5000.
上开发了一个客户端
我设置了护照身份验证。当我通过控制台或通过 postman 尝试使用 curl 命令时,一切正常。
我正在调用“/login”路由 (post),然后调用“/authrequired”来了解用户是否已通过身份验证。由于存储在 client-side 上的 session cookie,服务器可以识别用户。一切正常。
确实,每次我调用服务器时,用户都被识别为相同的 session ID。例如:84e3ff8a-b237-4899-aa1f-4a3d047e0c3f.
但是,当我在我的 Web 客户端应用程序中尝试相同的路由时,它不起作用。每次调用服务器时,都会定义一个新的 session ID。
这是 header 的请求:
Host: 127.0.0.1:3005
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0
Accept: application/json, text/plain, */*
Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://localhost:5000/
Content-Type: application/json;charset=utf-8
Content-Length: 33
Origin: http://localhost:5000
Connection: keep-alive
这是回复:
HTTP/1.1 200 OK
X-DNS-Prefetch-Control: off
X-Frame-Options: SAMEORIGIN
Strict-Transport-Security: max-age=15552000; includeSubDomains
X-Download-Options: noopen
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Access-Control-Allow-Origin: *
Content-Type: application/json; charset=utf-8
Content-Length: 76
ETag: W/"4c-UHE7wFwyy1/IvgicFsT1YzsRJZ4"
set-cookie: connect.sid=s%3A91e84b8a-63d2-4f01-b28b-882ce1cf1dd5.iIGDvmpU326AF34uAXg%2Bmy1ee28BUGw8TXrFBG0ogKc; Path=/; Expires=Fri, 28 Dec 2018 18:30:50 GMT
Date: Thu, 27 Dec 2018 18:30:50 GMT
Connection: keep-alive
正如我们所见,set-cookie header 存在。但是当我查看浏览器的 cookies 存储时,它不存在。我认为这就是服务器无法识别客户端的原因,因为客户端不会将 session cookie 发送到服务器。
这是我的服务器配置:
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
app.use(cors())
app.use(express.static('data/images'))
app.use(cookieParser())
app.use(session({
genid: (req) => {
return uuid()
},
store: new FileStore(),
secret: 'test',
resave: false,
saveUninitialized: false,
cookie: {
secure: false,
httpOnly: false,
path: '/',
maxAge: 1000 * 60 * 60 * 24
}
}))
app.use(passport.initialize())
app.use(passport.session())
这是我来自客户端的请求:
$http.post(self.url + '/login', {
idUser: $scope.name,
password: $scope.password
}, {
// withCredentials: true
})
我也将这两行配置添加到我的客户端应用程序中:
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
当我将 "withCredentials" 选项添加为 true 时,网络浏览器出现错误:
对“http://127.0.0.1:3005/login' from origin 'http://localhost:5000”处的 XMLHttpRequest 的访问已被 CORS 策略阻止:对飞行前请求的响应未通过访问控制检查:响应中 'Access-Control-Allow-Origin' header 的值不得为当请求的凭据模式为 'include' 时,通配符“*”。由 XMLHttpRequest 发起的请求的凭据模式由 withCredentials 属性控制。
我尝试了很多来自Whosebug的解决方案,但都失败了。
我希望拥有相同的 session ID 以便执行身份验证。
您不能为在 "Access-Control-Allow-Origin" 中使用通配符的服务器设置 "withCredentials" 标志。您必须 return 特定值“http://localhost:5000”并添加 header Access-Control-Allow-Credentials 和值 "true"。然后凭据将随请求一起发送。
我正在设置 Node.JS 服务器,使用 Express,运行 在端口 localhost:3005 上。我在 AngularJS、运行 端口 localhost:5000.
上开发了一个客户端我设置了护照身份验证。当我通过控制台或通过 postman 尝试使用 curl 命令时,一切正常。
我正在调用“/login”路由 (post),然后调用“/authrequired”来了解用户是否已通过身份验证。由于存储在 client-side 上的 session cookie,服务器可以识别用户。一切正常。
确实,每次我调用服务器时,用户都被识别为相同的 session ID。例如:84e3ff8a-b237-4899-aa1f-4a3d047e0c3f.
但是,当我在我的 Web 客户端应用程序中尝试相同的路由时,它不起作用。每次调用服务器时,都会定义一个新的 session ID。
这是 header 的请求:
Host: 127.0.0.1:3005
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0
Accept: application/json, text/plain, */*
Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://localhost:5000/
Content-Type: application/json;charset=utf-8
Content-Length: 33
Origin: http://localhost:5000
Connection: keep-alive
这是回复:
HTTP/1.1 200 OK
X-DNS-Prefetch-Control: off
X-Frame-Options: SAMEORIGIN
Strict-Transport-Security: max-age=15552000; includeSubDomains
X-Download-Options: noopen
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Access-Control-Allow-Origin: *
Content-Type: application/json; charset=utf-8
Content-Length: 76
ETag: W/"4c-UHE7wFwyy1/IvgicFsT1YzsRJZ4"
set-cookie: connect.sid=s%3A91e84b8a-63d2-4f01-b28b-882ce1cf1dd5.iIGDvmpU326AF34uAXg%2Bmy1ee28BUGw8TXrFBG0ogKc; Path=/; Expires=Fri, 28 Dec 2018 18:30:50 GMT
Date: Thu, 27 Dec 2018 18:30:50 GMT
Connection: keep-alive
正如我们所见,set-cookie header 存在。但是当我查看浏览器的 cookies 存储时,它不存在。我认为这就是服务器无法识别客户端的原因,因为客户端不会将 session cookie 发送到服务器。
这是我的服务器配置:
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
app.use(cors())
app.use(express.static('data/images'))
app.use(cookieParser())
app.use(session({
genid: (req) => {
return uuid()
},
store: new FileStore(),
secret: 'test',
resave: false,
saveUninitialized: false,
cookie: {
secure: false,
httpOnly: false,
path: '/',
maxAge: 1000 * 60 * 60 * 24
}
}))
app.use(passport.initialize())
app.use(passport.session())
这是我来自客户端的请求:
$http.post(self.url + '/login', {
idUser: $scope.name,
password: $scope.password
}, {
// withCredentials: true
})
我也将这两行配置添加到我的客户端应用程序中:
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
当我将 "withCredentials" 选项添加为 true 时,网络浏览器出现错误: 对“http://127.0.0.1:3005/login' from origin 'http://localhost:5000”处的 XMLHttpRequest 的访问已被 CORS 策略阻止:对飞行前请求的响应未通过访问控制检查:响应中 'Access-Control-Allow-Origin' header 的值不得为当请求的凭据模式为 'include' 时,通配符“*”。由 XMLHttpRequest 发起的请求的凭据模式由 withCredentials 属性控制。
我尝试了很多来自Whosebug的解决方案,但都失败了。
我希望拥有相同的 session ID 以便执行身份验证。
您不能为在 "Access-Control-Allow-Origin" 中使用通配符的服务器设置 "withCredentials" 标志。您必须 return 特定值“http://localhost:5000”并添加 header Access-Control-Allow-Credentials 和值 "true"。然后凭据将随请求一起发送。