【问题标题】:express - How to read HttpOnly cookie in request to API?express - 如何在对 API 的请求中读取 HttpOnly cookie?
【发布时间】:2023-03-12 08:44:01
【问题描述】:

当用户登录时,我会在响应中返回一个 HttpOnly cookie。

但是,当我在随后调用 API 时尝试读取 cookie 时,什么都没有

这是我制作 cookie 的方法:

var signOptions = {
    expiresIn: '30d',
    algorithm: 'RS256'
  }
  var CurrentDate = new Date()
  CurrentDate.setMonth(CurrentDate.getMonth() + 1)
  var cookieOptions = {
    httpOnly: true,
    expires: CurrentDate
  }

  const token = jwt.sign({ _id: user._id },
    fs.readFileSync(path.resolve('routes/keys/private.key'), 'utf8'),
    signOptions)

  res.status(200).cookie('stickyAccessJwt', token, cookieOptions).send('well done')

路线('/test'):

const express = require('express')
const router = express.Router()
const { CheckAuthorisation } = require('./middleware/checkAuthorisation')

router.get('/', CheckAuthorisation, async (req, res) => {
  res.send(':)')
})

module.exports = router

中间件(此处到达 401):

let checkAuthorisation = (req, res, next) => {
  var userJWT = req.cookies.stickyAccessJwt
  if (!userJWT) {
    res.status(401).send('Invalid or missing authorization token')
  } else {
    // 2. There's a token; see if it is a valid one and retrieve the payload

    var verifyOptions = {
      expiresIn: '30d',
      algorithm: ['RS256']
    }

    const userJWTPayload = jwt.verify(
      userJWT,
      fs.readFileSync(path.resolve('routes/keys/private.key'), 'utf8'),
      verifyOptions)

    if (!userJWTPayload) {
      // Kill the token since it is invalid
      res.clearCookie('stickyAccessJwt')
      res.status(401).send('Kill the token since it is invalid')
    } else {
      // 3. There's a valid token...see if it is one we have in the db as a logged-in user
      User.findOne({ '_id': userJWTPayload._id })
        .then(function (user) {
          if (!user) {
            res.status(401).send('User not currently logged in')
          } else {
            console.log('Valid user:', user.email)
            next()
          }
        })
    }
  }
}

这是我的 index.js

const Joi = require('joi')
Joi.objectId = require('joi-objectid')(Joi)
const bodyParser = require('body-parser')
const cors = require('cors')
const cookieParser = require('cookie-parser')
const mongoose = require('mongoose')
const express = require('express')
const app = express()
const register = require('./routes/register')
const login = require('./routes/login')
const test = require('./routes/test')

mongoose.connect('mongodb://localhost/stickywall', { useNewUrlParser: true })
  .then(() => console.log('Now connected to MongoDB!'))
  .catch(err => console.error('Something went wrong', err))
mongoose.set('useCreateIndex', true)

app.use(cors())
app.use(cookieParser())
app.use(express.json())
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
app.use('/register', register)
app.use('/login', login)
app.use('/test', test)

const port = process.env.PORT || 4000
app.listen(port, () => console.log(`Listening on port ${port}...`))

我不明白为什么req.cookies 是空的,是我遗漏了什么吗?

【问题讨论】:

标签: javascript node.js express cookies


【解决方案1】:
const token = req.body.token ||
    req.query.token ||
    req.headers['x-access-token'] ||
    req.cookies.token;

if (!token) {
   res.sendStatus(401)
}

【讨论】:

  • 顺便问一下,如果您使用的是 express.json(),为什么还要使用 body-parser?或者为什么在使用 body-parser 时使用 express.json()
  • 虽然欢迎使用此代码 sn-p,并且可能会提供一些帮助,但它会是 greatly improved if it included an explanation of howwhy 这解决了问题。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人!请edit您的答案添加解释,并说明适用的限制和假设。
  • @Jake 不确定 - 我一直在学习教程并随着时间的推移修改我的代码。我最初有一个存储在 localStorage 中的令牌,我会将其发送到服务器以进行验证,但是读到它为 XSS 攻击打开了(并且目前)沿着使用 HttpOnly cookie 的路线前进。你建议我只使用 body-parser 吗?
  • 为什么没有提到你在 localStorage 中存储了验证令牌,localStorage 中的变量可以很容易地用 javascript 更改,潜在的攻击者很容易执行 XSS 攻击,但也许你已经知道这一点,但如果你将使用 httpOnly cookie,你的方式是正确的,顺便说一下,我在你的代码中看到你已经在使用 httpOnly cookie,这让我对你想要实现的目标感到困惑
  • @Jake 因为我不再将它存储在 localStorage 中。你读过我的评论吗?我提到了 XSS 攻击,我也在这篇文章的标题中提到了 httpOnly
【解决方案2】:

res.cookie([ JWT_TOKEN=Bearer ${token}; secure; httponly; samesite=Strict;, ])

  1. 首先要安装cookie-parser库,它是一个中间件,这样express就可以管理cookie了:

$ npm install cookie-parser

  1. 然后转到配置 Express 应用程序的位置,并将 cookie-parser 库添加为中间件

$const express = require('express');
$const cookieParser = require('cookie-parser');
$app.use(cookieParser());

3.现在我们的 Express 应用程序可以为我们完成所有 cookie 解析工作!

req.cookies.JWT_TOKEN

  1. 前面如果你使用axios一定要在配置中始终设置“withCredentials: true”,

const config = { headers: { 'Content-Type': 'application/json', },withCredentials: true,}

axios
  .post(
    'http://localhost:3008/api/auth/login',
    {
      username: target.username.value,
      password: target.password.value,
    },
    config
  )
  .then((data) => JSON.stringify(data, null, 2))
  .then((result) => console.log(result))
  .catch((err) => console.log('[Control Error ] ', err))

}`

!!! HTTP cookie 在对服务器的所有请求中自动发送。结束

【讨论】:

    猜你喜欢
    • 2017-06-08
    • 2010-09-06
    • 2021-08-14
    • 1970-01-01
    • 2011-12-25
    • 1970-01-01
    • 2021-02-09
    • 2019-04-24
    • 1970-01-01
    相关资源
    最近更新 更多