Back

Node Auth Tutorial (JWT) #9 - Cookies Primer

- The Net Ninja

資料來源


重點摘要

  • cookie 是 server 在 browser 儲存資訊的一種方式。browser 向 server 發送 request 時,server 可以根據網頁應用需求,以回傳 cookie 的方式將資訊儲存在 browser。
  • cookie 跟隨 response 返回 browser (夾帶於 response header),之後 cookie 便儲存在 browser 中,下次對相同網域發送 request 時就會攜帶該 cookie 資訊。
  • cookie 狀態若涉及身分驗證則可能隱含 Cross Site Request Forgery (CSRF) 風險,詳情可參閱 OWASP

  const express = require('express') // npm i express
  const app = express()

  app.get('/set-cookies', (req, res) => {
    res.setHeader('Set-Cookie', 'newUser=true; HttpOnly')
    res.send('you got the cookies!')
  })

  app.listen(3000)

運行上述程式碼後連入 http://localhost:3000/set-cookies 即可獲得 cookie


  Browser cookies
Browser cookies
  • Expires / Max-Age: Session 表示一旦瀏覽器關閉,該 cookie 即失效
  • 可以透過 document.cookie 取得該網域下所有 cookies (HttpOnly 例外,稍後說明),取得的 cookies 以字串型態首尾相連,例如 "newUser=true; isActive=true; _ga=GA2.1.6348925716.3527694218"

使用 cookie-parser 讓 cookie 操作更加容易

  const express = require('express')
  const cookieParser = require('cookie-parser') // npm i cookie-parser
  const app = express()

  // middleware
  app.use(cookieParser())

  app.get('/set-cookies', (req, res) => {
    // 使用 cookie 方法,將 newUser 設為 false (create/update 寫法相同)
    res.cookie('newUser', false)
    res.send('you got the cookies!')
  })

  app.listen(3000)

res.cookie() 除了 Name 和 Value 之外,第三個參數可以用來設定 cookie 屬性,以下為常見屬性:

  • maxAge:經過多少毫秒後失效
  • secure:僅在 https 環境下才會作用
  • httpOnly:僅能夠透過 http protocol 傳遞資訊,在前端透過 document.cookie 無法取得
  const express = require('express')
  const cookieParser = require('cookie-parser')
  const app = express()

  app.use(cookieParser())

  app.get('/set-cookies', (req, res) => {
    res.cookie('isEmployee', true, {
      maxAge: 1000 * 60 * 60 * 24, // 1 天
      secure: true,
      httpOnly: true
    })
    res.send('you got the cookies!')
  })

  app.get('/read-cookies', (req, res) => {
    // 因為前面有 cookie-parser middleware 才能透過這樣的方式取得所有 cookies (得到的是物件形式)
    const cookies = req.cookies
    // 轉成 JSON 後回傳
    res.json(cookies)
  })

  app.listen(3000)
Licensed under CC BY-NC-SA 4.0
comments powered by Disqus