快速会话在请求之间不持久
Express Session Not Persisting Between Requests
我在使用 express-session
时遇到问题。会话数据在请求之间不持久。
正如您在下面的代码中看到的那样,/join
路由设置了一些会话属性,但是当 /surveys
路由被命中时,会话数据不可用。 req.session.loggedIn
returns undefined
在 /surveys
路线中。
require('dotenv').config()
const cors = require('cors')
const express = require('express')
const open = require('amqplib').connect(process.env.RABBIT_SERVER)
const session = require('express-session')
const subscribeValidator = require('./src/validators/subscribe')
const { validationResult } = require('express-validator/check')
const app = express()
app.set('trust proxy', 1)
app.use(session({
name: 'giro',
secret: process.env.SESSION_SECRET,
saveUninitialized: false,
cookie: { secure: false },
maxAge: process.env.SESSION_EXPIRY,
resave: false
}))
app.use(express.json())
app.use(cors())
app.post('/join', subscribeValidator, function (req, res) {
/*
if(session.loggedIn) {
return res.send(JSON.stringify({
redirect: '/surveys'
}))
}
*/
const data = {
firstname: req.body.firstname,
surname: req.body.surname,
email: req.body.email,
birthday: req.body.birthday,
gender: req.body.gender,
isSubscribed: req.body.isSubscribed
}
const errors = validationResult(req.body)
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() })
}
open
.then(conn => conn.createChannel())
.then(ch => ch
.assertQueue('subscribe')
.then(ok => {
ch.sendToQueue('subscribe', Buffer.from(JSON.stringify(data)))
req.session.firstname = data.firstname
req.session.email = data.email
req.session.isSubscribed = data.isSubscribed
req.session.confirmed = false
req.session.loggedIn = true
req.session.save()
res.send(JSON.stringify({
redirect: '/surveys',
firstname: data.firstname,
email: data.email
}))
})
)
.catch(console.warn)
})
app.post('/surveys', (req, res) => {
console.log(req.session.loggedIn)
if (!req.session.loggedIn) {
return res.send(JSON.stringify({
error: {
type: 'auth',
message: 'You must be logged in to view and complete surveys. Have you signed up?'
}
}))
}
res.send(JSON.stringify({
surveys: [
'one',
'two',
'three'
]
}))
})
// Start the server :)
app.listen(3000, () =>
console.log('Server running at: http://localhost:3000')
)
我已经检查了很多与我的问题无关的 SO 帖子,一遍又一遍地阅读文档,但我似乎仍然遗漏了一些东西。
谢谢
在@jfriend00 的帮助下我解决了这个问题。因为 API 与发出请求的 CDN 位于不同的端口,所以当从 CDN 向 API 发出 xhr
请求时,它属于跨源请求。尽管我启用了 cors
以便 cookie 跨源工作,但您必须进行一些调整。
首先,我必须像这样配置 express-cors
:
app.use(cors({
origin: 'http://localhost:1313',
credentials: true
}))
这会将 Access-Control-Allow-Origin
header 值设置为 http://localhost:1313
。不能使用通配符,否则将无法通过 pre-flight 检查。
crednetials
属性 将 Access-Control-Allow-Credentials
header 值设置为 true
。同样,如果没有这个,飞行前将失败。
在主机上发出请求时,我也必须使用 withCredentials
。我正在使用 superagent,所以我是这样做的:
componentDidMount () {
request
.post('http://localhost:3000/surveys')
.withCredentials()
.set('accept', 'json')
.end((err, res) => {
this.setState({ isLoading: false })
...
})
}
现在可以使用了:)
我在使用 express-session
时遇到问题。会话数据在请求之间不持久。
正如您在下面的代码中看到的那样,/join
路由设置了一些会话属性,但是当 /surveys
路由被命中时,会话数据不可用。 req.session.loggedIn
returns undefined
在 /surveys
路线中。
require('dotenv').config()
const cors = require('cors')
const express = require('express')
const open = require('amqplib').connect(process.env.RABBIT_SERVER)
const session = require('express-session')
const subscribeValidator = require('./src/validators/subscribe')
const { validationResult } = require('express-validator/check')
const app = express()
app.set('trust proxy', 1)
app.use(session({
name: 'giro',
secret: process.env.SESSION_SECRET,
saveUninitialized: false,
cookie: { secure: false },
maxAge: process.env.SESSION_EXPIRY,
resave: false
}))
app.use(express.json())
app.use(cors())
app.post('/join', subscribeValidator, function (req, res) {
/*
if(session.loggedIn) {
return res.send(JSON.stringify({
redirect: '/surveys'
}))
}
*/
const data = {
firstname: req.body.firstname,
surname: req.body.surname,
email: req.body.email,
birthday: req.body.birthday,
gender: req.body.gender,
isSubscribed: req.body.isSubscribed
}
const errors = validationResult(req.body)
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() })
}
open
.then(conn => conn.createChannel())
.then(ch => ch
.assertQueue('subscribe')
.then(ok => {
ch.sendToQueue('subscribe', Buffer.from(JSON.stringify(data)))
req.session.firstname = data.firstname
req.session.email = data.email
req.session.isSubscribed = data.isSubscribed
req.session.confirmed = false
req.session.loggedIn = true
req.session.save()
res.send(JSON.stringify({
redirect: '/surveys',
firstname: data.firstname,
email: data.email
}))
})
)
.catch(console.warn)
})
app.post('/surveys', (req, res) => {
console.log(req.session.loggedIn)
if (!req.session.loggedIn) {
return res.send(JSON.stringify({
error: {
type: 'auth',
message: 'You must be logged in to view and complete surveys. Have you signed up?'
}
}))
}
res.send(JSON.stringify({
surveys: [
'one',
'two',
'three'
]
}))
})
// Start the server :)
app.listen(3000, () =>
console.log('Server running at: http://localhost:3000')
)
我已经检查了很多与我的问题无关的 SO 帖子,一遍又一遍地阅读文档,但我似乎仍然遗漏了一些东西。
谢谢
在@jfriend00 的帮助下我解决了这个问题。因为 API 与发出请求的 CDN 位于不同的端口,所以当从 CDN 向 API 发出 xhr
请求时,它属于跨源请求。尽管我启用了 cors
以便 cookie 跨源工作,但您必须进行一些调整。
首先,我必须像这样配置 express-cors
:
app.use(cors({
origin: 'http://localhost:1313',
credentials: true
}))
这会将 Access-Control-Allow-Origin
header 值设置为 http://localhost:1313
。不能使用通配符,否则将无法通过 pre-flight 检查。
crednetials
属性 将 Access-Control-Allow-Credentials
header 值设置为 true
。同样,如果没有这个,飞行前将失败。
在主机上发出请求时,我也必须使用 withCredentials
。我正在使用 superagent,所以我是这样做的:
componentDidMount () {
request
.post('http://localhost:3000/surveys')
.withCredentials()
.set('accept', 'json')
.end((err, res) => {
this.setState({ isLoading: false })
...
})
}
现在可以使用了:)