Skip to main content

Node.js 获取操作 Cookie

Cookie 是服务器发送给浏览器并保存在本地的一小块数据,它会在浏览器下次发起请求时携带给服务器,用于辨别用户身份。

继前面的 Node.js 项目示例,在启动服务时获取并解析 Cookie:

app.js
// ...

const serverHandle = (req, res) => {
// ...
// 统一解析 Cookie
req.cookie = {}
const cookieStr = req.headers.cookie || '' // k1=v1;k2=v2
cookieStr.split(';').forEach(item => {
if (!item) return
const itemArr = item.split('=')
const itemKey = itemArr[0]
const itemVal = itemArr[1]
req.cookie[itemKey] = itemVal
});
console.log('req.cookie: ', req.cookie)
// ...
}

module.exports = serverHandle

yarn dev 启动服务,访问 http://127.0.0.1:7676/,并设置 Cookie:

再次访问 http://127.0.0.1:7676/ 时,控制台将打印 Cookie:

2、简单的登录验证

这里根据 Cookie 中有无 username 来判断用户是否已经登录,举个例子:

src/router/user.js
// ...
const { SuccessModel, ErrorModel } = require('../model/resModel')

const handleUserRouter = (req, res) => {
const method = req.method

// ...

// 登陆验证的测试
if (method === 'GET' && req.path === '/api/user/login-test') {
if (req.cookie.username) {
return Promise.resolve(new SuccessModel())
}
return Promise.resolve(new ErrorModel('尚未登录'))
}
}

module.exports = handleUserRouter

当 Cookie 中没有 username 时,访问 http://127.0.0.1:7676/api/user/login-test,结果如下:

这里临时在控制台设置个简单的 Cookie:document.cookie='username=leophen',再次访问结果如下:

一般情况下,Cookie 的修改应该在后端操作

点击查看操作 Cookie 属性汇总

src/router/user.js
const { login } = require('../controller/user')
const { SuccessModel, ErrorModel } = require('../model/resModel')

const handleUserRouter = (req, res) => {
const method = req.method

// 登录
if (method === 'GET' && req.path === '/api/user/login') {
const { username, password } = req.query
const result = login(username, password)

return result.then(data => {
if (data.username) {
// 操作 Cookie
res.setHeader('Set-Cookie', `username=${data.username}; path=/`)
return new SuccessModel()
}
return new ErrorModel('登录失败')
})
}
// ...
}

module.exports = handleUserRouter

访问 http://127.0.0.1:7676/api/user/login?username=dorki&password=123,可看到浏览器添加了 Cookie:

可通过设置 HttpOnly 来阻止 JS 访问和修改 Cookie:

res.setHeader('Set-Cookie', `username=${data.username}; path=/`)
res.setHeader('Set-Cookie', `username=${data.username}; path=/; HttpOnly`)

另外,可以设置 Cookie 的有效时间 Expires,过了该时间浏览器会自动删除 Cookie,提升安全性:

// 获取 Cookie 的过期时间
const getCookieExpires = () => {
const d = new Date()
d.setTime(d.getTime() + (24 * 60 * 60 * 1000))
return d.toGMTString()
}

res.setHeader('Set-Cookie', `username=${data.username}; path=/; HttpOnly`)
res.setHeader('Set-Cookie', `username=${data.username}; path=/; HttpOnly; Expires=${getCookieExpires()}`)

点击查看 Node.js 操作 Cookie 的完整代码

通过 Cookie 保存 username 判断是否登录的情况不安全,会暴露 username。

可以通过存储在 Session 中来进行优化。

Express 使用中间件 cookie-parser,不需要统一解析 Cookie 的步骤,直接操作 Cookie 即可:

// 读取 Cookie
req.cookies.username

// 设置 Cookie
res.cookie("username", "Leophen" , {
domain: '.example.com',
path: '/admin',
secure: true
})

// 清除 Cookie
res.clearCookie('username', {
path: '/admin' // 这里的 path 要和设置该 cookie 时一致
});

点击查看 Koa 获取及设置 Cookie 详情

// 获取 Cookie
ctx.cookies.get(name, [options])

// 设置 Cookie
ctx.cookies.set(name, value, [options])