JWT在node中的簡單應用
阿新 • • 發佈:2018-11-23
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.使用者註冊,
- 使用者登陸,
- 使用者跳轉效驗
// 後端伺服器
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