JWT簡介
- 官方是這樣介紹的:
JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.(JSON Web Token(JWT)是一個開放標準(RFC 7519),它定義了一種緊湊且獨立的方式,可以在各方之間作為JSON物件安全地傳輸資訊。 此資訊可以通過數字簽名進行驗證和信任。 JWT可以使用祕密(使用HMAC演算法)或使用RSA或ECDSA的公鑰/私鑰對進行簽名。)
-
用途
授權和安全傳輸資訊
-
token的結構 Header.Payload.Signature
- Header 通常由兩部分組成:令牌的型別,即JWT,以及正在使用的雜湊演算法,例如HMAC SHA256或RSA。
- Payload 加密的資料
- Signature 簽名
應用
知道了JWT的用途後,我們就開始針對授權來結合node做簡單的實現。
-
版本號
- cnpm@6.0.0
- npm@6.4.1
- node@11.1.0
-
流程
-
使用者還沒登入時,只能訪問首頁、註冊、登入介面,如下圖
-
登入過後能獲取自己的資訊
-
如果沒輸入token,則提示沒有找到token,當然可以重定位到首頁
-
輸入錯誤的token,提示使用者未登入
-
-
目錄結構
說明:config.js為全域性配置檔案,user.js為Mongo資料庫對應的user實體,index.js為專案入口檔案。
-
config.js
module.exports = { 'network' : { 'port':8080 }, 'salt': '0vAXJ@2R%PAxL9*Y#vLc8VQuLGk0BzdD', 'jwtsecret': 'myjwttest', 'database': 'mongodb://127.0.0.1:27017/test' }; 複製程式碼
-
user.js
var mongoose = require('mongoose'); var Schema = mongoose.Schema; // 返回一個mongo使用者庫例項 module.exports = mongoose.model('User', new Schema({ name: String, password: String })); 複製程式碼
-
index.js
const express = require('express'); const app = express(); const crypto = require('crypto'); const util = require('util'); const bodyParser = require('body-parser');//request.body起效果而用 const mongoose = require('mongoose');//MongoDB const jwt = require('jsonwebtoken'); // 使用jwt簽名 const config = require('./config'); // 引入配置 const User = require('./user'); // 引入mongo使用者庫例項 // 連線mongo mongoose.connect(config.database); // 設定加密祕鑰 app.set('superSecret', config.jwtsecret); //設定request.body有效 app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); app.listen(config.network.port); // 首頁 app.get('/', function (req, res) { res.send('這裡是首頁http://127.0.0.1:' + config.network.port + "/api"); }); // 註冊 app.post('/register', async function (req, res) { if (req.body.name && req.body.password) { const salt = config.salt; const pwdEnc = await util.promisify(crypto.pbkdf2)(req.body.password, salt.toString('base64'), 10000, 64, 'sha256'); var user = new User({ name: req.body.name, password: pwdEnc }); user.save(function (err) { if (err) throw err; console.log('註冊成功'); res.json({ success: true }); }); } else { res.json({ success: false, msg: "錯誤引數" }); } }); // 登入,登入成功返回JWT的Token 驗證使用者名稱密碼 app.post('/login', function (req, res) { User.findOne({ name: req.body.name }, async function (err, user) { if (err) throw err; if (!user) { res.json({ success: false, message: '未找到授權使用者' }); } else if (user) { const salt = config.salt; const pwdEnc = await util.promisify(crypto.pbkdf2)(req.body.password, salt.toString('base64'), 10000, 64, 'sha256'); if (user.password != pwdEnc) { res.json({ success: false, message: '使用者密碼錯誤' }); } else { var token = await util.promisify(jwt.sign)({ user: user, }, app.get('superSecret'), { expiresIn: '4h', }); res.json({ success: true, message: '請使用您的授權碼', token: token }); } } }); }); // 建立需要授權的介面 var apiRoutes = express.Router(); //校驗機制 apiRoutes.use(async function (req, res, next) { // 獲取傳過來的token var token = req.headers['x-access-token']; if (token) { // 解碼token獲取使用者資訊 decoded為加密前的內容 util.promisify(jwt.verify)(token, app.get('superSecret')).then(function(data){ req.decoded = data; next(); //繼續下一步路由 }).catch((error)=>{ res.status(400).json({message: '使用者未登入',error: error}); }); } else { // 沒有拿到token 返回錯誤 return res.status(403).send({ success: false, message: '沒有找到token.' }); } }); //獲取加密的資訊 apiRoutes.get('/', function (req, res) { req.decoded.user.password = undefined; res.json(req.decoded.user); }); //獲取所有使用者 apiRoutes.get('/list', function (req, res) { User.find({}, function (err, users) { res.json(users); }); }); // 註冊API路由 app.use('/api', apiRoutes); 複製程式碼
成東
廣州蘆葦科技Java開發團隊
蘆葦科技-廣州專業網際網路軟體服務公司
抓住每一處細節 ,創造每一個美好
關注我們的公眾號,瞭解更多
想和我們一起奮鬥嗎?lagou搜尋“ 蘆葦科技 ”或者投放簡歷到 server@talkmoney.cn 加入我們吧
關注我們,你的評論和點贊對我們最大的支援