1

我很难让我的反应应用程序与 cookie-session 一起工作。当我查看我的网络并注册时,我确实发送了一个 Set-Cookie。这些是我的响应标头:

 Connection:keep-alive
Content-Type:application/json
Date:Fri, 09 Feb 2018 22:32:02 GMT
Set-Cookie:session=eyJ1c2VySWQiOjEwOX0=; path=/; expires=Mon, 19 Feb 2018 22:32:02 GMT; httponly
Set-Cookie:session.sig=o975QwcyzldDFzSPzbp2S4Qe_M4; path=/; expires=Mon, 19 Feb 2018 22:32:02 GMT; httponly
Transfer-Encoding:chunked
X-Powered-By:Express

请求标头:

Accept:application/json
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.9
Connection:keep-alive
Content-Length:59
Content-Type:application/json
Host:localhost:5000
Origin:http://localhost:5000
Referer:http://localhost:5000/signup
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36

但是,我注意到我的 cookie 没有存储在浏览器中。我相信cookies应该由浏览器自动存储?这是我的代码:

const express = require('express')
const bodyParser = require('body-parser')
const cookieParser = require('cookie-parser')
const cookieSession = require('cookie-session')
const bcrypt = require('bcrypt')
const port = process.env.PORT || 5000
const app = express()
const pg = require('pg')
const conString = "postgres://postgres:postgres@localhost:5432/test"
const db = new pg.Client(conString)
let User


app.use(bodyParser.urlencoded({ extended: true }))
app.use(cookieParser())
app.use(cookieSession({
    name: 'session',
    secret: "booboo",
    httpOnly: true,
    // Cookie Options
    maxAge: 24 * 60 * 60 * 1000 * 10 // 24 hours * 10 days
  }))

app.use(express.json())
app.use(express.static(__dirname + '/client/build'))

app.use(function(req,res ,next){
console.log(req.session)
if(req.method !== 'POST')
    res.sendFile(__dirname + '/client/build/index.html')

if(req.headers.accept === 'application/json')
    next() 
})


app.route('/signup')
    .post((req, res) => {
        const sendError = (msg) => {
            res.status(400).send({error: msg})
        }

        if(!User.validateBeforeCreate({email: req.body.user.email, password: req.body.user.password}, sendError))
            return

        const salt = bcrypt.genSaltSync();
        const password = bcrypt.hashSync(req.body.user.password, salt);
        User.create({email: req.body.user.email, password: password}, (err, user) => {
            if(err !== null){
                if(err.code === '23505')
                    sendError('Account with that email already exists.')
            }
            else{
                req.session.userId = user.user_id
                res.writeHead(201, {"Content-Type": "application/json"})
                res.end()
                console.log(req.session)
                console.log(req.session.userId)
            }
        })
    })

我在注册时的 console.log 打印了这个:Session {userId: 103} 103

同时我的 console.log 在我注册并访问一个页面以接收我的反应应用程序后,我得到了这个打印输出(可能是因为浏览器没有 cookie): Session {} ,我尝试将 httpOnly 设置为 true 和 false . 结果相同。

我究竟做错了什么?

4

2 回答 2

0

经过几个小时的敲击键盘后,我想通了。出于某种原因,它不会设置 cookie。得到的工作,但我花了一段时间才到达那里。我花了一段时间弄清楚它是否有反应。但是不,如果我将它设置在 get 操作上它会起作用。所以后来我认为这是一个安全问题。而且我发现我需要在客户的提取中添加一个具有“同源”的凭据属性。我在错误的位置放置了一个 next() 。现在一切正常。所以总而言之,我所做的所有更改,4 行。感谢 Taylor Swanson 和这篇文章: 为什么浏览器在 AJAX 请求返回后不设置 cookie?

name: 'session',
secret: "booboo",
httpOnly: true,
path: "/",
domain: "localhost"

处理提交是一个客户端回调:

handleSubmit = (event) => {
        event.preventDefault()
        fetch('/signup',{
            headers:{
              'Accept': 'application/json',
              'Content-Type': 'application/json'
            },
            credentials: 'same-origin',
            method: 'post',
            body: JSON.stringify({user: {...this.state}})
          })
    }

我的新服务器代码如下所示:

app.use(bodyParser.urlencoded({ extended: true }))
app.use(cookieParser())
app.use(cookieSession({
    name: 'session',
    secret: "booboo",
    httpOnly: true,
    path: "/",
    domain: "localhost"
    // Cookie Options
  }))

app.use(express.json())
app.use(function(req, res, next){
    if(req.method === 'GET' && req.cookies.session === undefined)
        req.session.userId = null
    else
        console.log(req.session.userId)

    next()
})
app.use(express.static(__dirname + '/client/build/'))
app.use(function(req,res ,next){
    if(req.method === 'GET')
        res.sendFile(__dirname + '/client/build/index.html')

    if(req.headers.accept === 'application/json')
        next()
})

app.route('/signup')
    .post((req, res, next) => {
        const sendError = (msg) => {
            res.status(400).send({error: msg})
        }

        if(!User.validateBeforeCreate({email: req.body.user.email, password: req.body.user.password}, sendError))
            return

        const salt = bcrypt.genSaltSync();
        const password = bcrypt.hashSync(req.body.user.password, salt);
        User.create({email: req.body.user.email, password: password}, (err, user) => {
            if(err !== null){
                if(err.code === '23505')
                    sendError('Account with that email already exists.')
            }
            else{
                req.session.userId = user.user_id
                res.writeHead(201, {"Content-Type": "application/json"})
                res.end()
                console.log(req.session)
                console.log(req.session.userId)
            }
            next()
        })
    })
于 2018-02-10T03:09:29.887 回答
0

看起来您没有在 cookie 对象中设置域,因此浏览器正在丢弃 cookie。我还建议在您的浏览器中打开开发人员工具并检查服务器发送的标头以查看传输的 cookie 的样子。

尝试:

app.use(cookieSession({
  name: 'session',
  secret: "booboo",
  httpOnly: true,
  domain: "example.com",
  // Cookie Options
  maxAge: 24 * 60 * 60 * 1000 * 10 // 24 hours * 10 days
}))
于 2018-02-09T22:37:58.173 回答