官方給出的定義是:
JSON Web Token(JWT)是一個開放標準(RFC 7519),它定義了一種緊湊的、獨立的方式,用於安全地在當事人之間傳遞信息做爲一個JSON對象。這些信息能夠被驗證和信任,由於它是數字簽名的。JWTs可使用一個secret (使用HMAC算法)或使用RSA的公鑰/私鑰對來簽名。 文中咱們使用公私鑰的加密方式。html
由下面三個部分組成一個token字符串git
Headergithub
Payload ,包含三個類型,自定義部分能夠存儲一些信息,如:用戶信息、角色等;web
Signature算法
這裏直接使用官網的圖mongodb
這裏使用express來建立一個服務
建立一個入口文件,主要用於一些中間件的掛載express
//index.js const express = require('express') const app = express() // 使用body-parser獲取請求body const bodyParser = require('body-parser'); const cookieParser = require('cookie-parser') // 引入路由中間件 const routerAdmin = require('./app/router-admin') app.use(bodyParser.json()); // for parsing application/json app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded app.use(cookieParser()) // 加載路由模塊 app.use('/admin',routerAdmin); app.listen(3000,function(){ console.log('port 3000 start') })
而後建立一個 app/router-admin.js 生成須要用到認證的路由中間件,這裏我是在mongodb中取的用戶信息,也能夠自行模擬數據json
//router-admin.js const express = require('express') const router = express.Router() var MongoClient = require('mongodb').MongoClient; const jwt = require('jsonwebtoken') const fs = require('fs') // const secretStr = 'sdfsjfklsjfiewjwoieow' // 根據mongodb生成的_id查詢數據 var ObjectId = require('mongodb').ObjectId var url = "mongodb://localhost:27017/"; var payload = { user : 'william', admin : true } router.post('/login',function(req,res){ let name = req.body.name, pwd = req.body.pwd; var cert = fs.readFileSync('./private.key') MongoClient.connect(url, function(err, db) { if (err) throw err; var dbo = db.db("blog"); var noSqlStr = {name:name,pwd:pwd} dbo.collection("userlist"). find(noSqlStr).toArray(function(err, result) { // 返回集合中全部數據 if (err) throw err; // console.log(result); // 驗證經過,服務端回傳token if(!!result.length){ var token = jwt.sign(payload, cert, { algorithm: 'RS256' ,expiresIn:'30s'}); res.send({ status : true, msg : '', token : token }) } db.close(); }); }); }) // 驗證jsonwebtoken是否過時的中間件,在login接口後面執行,除了login接口的請求外,其餘接口都須要驗證token router.use(function jwtVerify(req, res, next) { let token = req.get('token') console.log(token) var cert = fs.readFileSync('./public.key'); // 先解密 jwt.verify(token, cert,function(err,decoded){ if(err || !decoded) res.send({data:null,status:false,msg:err}) if(decoded.user == payload.user){ next(); } }); }); router.get('/search',function(req,res){ res.send({data:'查詢成功',msg:'',status:true}) }) module.exports = router
由於這裏使用的是公私鑰的加密方式,需使用ssh-keygen生成公私鑰安全
私鑰生成:ssh-keygen -t rsa -b 2048 -f private.key 公鑰生成:openssl rsa -in private.key -pubout -outform PEM -out public.key