1. 程式人生 > >JWT在node中的簡單應用

JWT在node中的簡單應用

JSON Web Token(縮寫 JWT)是目前最流行的跨域認證解決方案。

是為了在網路應用環境間傳遞宣告而執行的一種基於JSON的開放標準((RFC 7519).該token被設計為緊湊且安全的,特別適用於分散式站點的單點登入(SSO)場景。

主要解決的問題

  • 跨域認證的問題
  • 單點登陸的問題
  • 省去服務端讀取Session的步驟,這樣更符合RESTful的規範

JWT 構成

  • header(頭部,包括類別(typ)、加密演算法(alg))
  • payload(載荷,需要傳遞的使用者資訊)
  • signature(簽名,根據alg演算法與私有祕鑰進行加密得到的簽名字串)

//SECREATE_KEY 是我們儲存再服務端服務端的隨機字串,用來生成和效驗簽名的時候使用
// 1. Headers
let header{
  "alg": "HS256",
  "typ": "JWT"
}
// 2. Claims
let payload= {
  "age": "12",
  "name": "leo"
}
// 3. Signature
// 根據alg演算法與私有祕鑰進行加密得到的簽名字串;
// 這一段是最重要的敏感資訊,只能在服務端解密;
let sign = HMACSHA256(  
    base64UrlEncode(header) + "." +
    base64UrlEncode
(payload), SECREATE_KEY )

node中使用jwt

  • 環境準備
    • 配置伺服器,mongodb
    • 安裝mongoose外掛
    • 安裝Express, 這裡是為了方便學習,可以使用node原生寫,也是ok的就是麻煩一點
    • 安裝node的jwt模組npm i jwt-simple --save
  • 這裡為了做效驗,定義一個簡單的sechema
1.新建一個目錄,命名為amin
2.進入admin目錄,新建目錄model,app.js, config.js,
3.進入model目錄,新建user.
js該檔案用來連結mongodb // admin/model/user.js 程式碼 // 操作資料化邏輯 let mongoose = require('mongoose') let config = require('../config') let { db_url } = config // 連線資料庫 mongoose.connect(db_url, {useNewUrlParser: true}) // 骨架Schema let UserSchema = new mongoose.Schema({ username: String, password: String }) // 建立一個模型 let User = mongoose.model('User', UserSchema) // 對外暴露模型 module.exports = User // admin/config 內容 // 配置常量 module.exports = { db_url: 'mongodb://localhost:27017', // 本地mongodb的連結地址 secret: 'hello wold' // 生成token的時候用的金鑰 }
  • admin/app.js中寫主程式

思路如下,實現一個簡單的使用者登陸註冊功能

1.使用者註冊,

  1. 使用者登陸,
  2. 使用者跳轉效驗
// 後端伺服器
let Express = require('express')
let bodyParser = require('body-parser')
let jwt = require('jwt-simple')
let config = require('./config')
let { secret } = config

// 返回一個監聽函式
let app = Express()
// 中介軟體需要處理的內容
app.use(bodyParser.json())
let User = require('./model/user')

// 需要實現的功能
// 處理跨域, 使用cors實現
app.use(function(req, res, next) {
  res.setHeader('Access-Control-Allow-Orgin', '*') // 允許的域名
  res.setHeader('Access-Control-Allow-headers', 'Content-Type,Authorization') // 允許的請求頭
  res.setHeader('Access-Control_Allow-Methods', 'GET,POST,DELETE,PUT,OPTIONS')
  if (req.method === 'OPTIONS') {
    res.end()
  } else {
    next()
  }
  
})
// 1.使用者註冊
app.post('/reg', async function (req, res, next) {
  let user = req.body 
  try {
    // 新增以後返回的結果
    user = await User.create(user)
    
    res.json({
      code: 0,
      data: {
        user: {id: user._id, name: user.username}
      },
      msg: '註冊成功'
    })

  } catch (e) {
    res.json({
      code: 1,
      msg: '註冊失敗'
    })
  }
  
})
// 2.使用者登入
app.post('/login', async function (req, res, next) {
  let user = req.body
  
  user = await User.findOne(user)
  
  if (user) {
    // 使用者存在,返回登入成功
    let token = jwt.encode({
      id: user._id,
      username: user.username
    }, secret)
    res.json({
      code: 0,
      data: {
        token
      }
    })
  } else {
    res.json({
      code: 1,
      meg: '使用者不存在'
    })
  }
})

// 4.公用效驗許可權中介軟體
let auth = (req, res, next) => {
  let authorization = req.headers['authorization']
  
  if (authorization) {
    let token = authorization.split(' ')[1]
    // 解析token
    try { // 如果被篡改,就會無法解析報錯
      let user = jwt.decode(token, secret)
      req.user = user
      next() // 取出token表示的內容 表示沒有被篡改過
    } catch (e) {
      res.status(404).send('Not Allowed')
    }
  } else {
    res.status(404).send('Not Allowed')
  }
}
// 使用者效驗可以通過 Authorization 
//3. 解析請求頭,拿到token, authorization: Bearer token
app.post('/order', auth, async function (req, res, next) {
  res.json({
    code: 0,
    data: req.user
  })
})

app.listen(3000)

總結

以上是簡單的jwt在node中的應用,當然我們還可以加入過期時間,別的什麼的,具體是自己的使用常見,我只拋磚引玉

傳送夢: jwt-simple