摘要:此信息可以通過數(shù)字簽名進行驗證和信任。用途授權(quán)和安全傳輸信息的結(jié)構(gòu)通常由兩部分組成令牌的類型,即,以及正在使用的散列算法,例如或。加密的數(shù)據(jù)簽名應用知道了的用途后,我們就開始針對授權(quán)來結(jié)合做簡單的實現(xiàn)。
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對象安全地傳輸信息。
此信息可以通過數(shù)字簽名進行驗證和信任。
JWT可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公鑰/私鑰對進行簽名。)
用途
授權(quán)和安全傳輸信息
token的結(jié)構(gòu)
Header.Payload.Signature
Header
通常由兩部分組成:令牌的類型,即JWT,以及正在使用的散列算法,例如HMAC SHA256或RSA。
Payload
加密的數(shù)據(jù)
Signature
簽名
知道了JWT的用途后,我們就開始針對授權(quán)來結(jié)合node做簡單的實現(xiàn)。
版本號
cnpm@6.0.0
npm@6.4.1
node@11.1.0
流程
用戶還沒登錄時,只能訪問首頁、注冊、登錄接口,如下圖
登錄過后能獲取自己的信息
如果沒輸入token,則提示沒有找到token,當然可以重定位到首頁
輸入錯誤的token,提示用戶未登錄
目錄結(jié)構(gòu)
說明:config.js為全局配置文件,user.js為Mongo數(shù)據(jù)庫對應的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); // 設(shè)置加密秘鑰 app.set("superSecret", config.jwtsecret); //設(shè)置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: "錯誤參數(shù)" }); } }); // 登錄,登錄成功返回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: "未找到授權(quán)用戶" }); } 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: "請使用您的授權(quán)碼", token: token }); } } }); }); // 創(chuàng)建需要授權(quán)的接口 var apiRoutes = express.Router(); //校驗機制 apiRoutes.use(async function (req, res, next) { // 獲取傳過來的token var token = req.headers["x-access-token"]; if (token) { // 解碼token獲取用戶信息 decoded為加密前的內(nèi)容 util.promisify(jwt.verify)(token, app.get("superSecret")).then(function(data){ req.decoded = data; next(); //繼續(xù)下一步路由 }).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開發(fā)團隊
蘆葦科技-廣州專業(yè)軟件外包服務公司
提供微信小程序、APP應用研發(fā)、UI設(shè)計等專業(yè)服務,專注于互聯(lián)網(wǎng)產(chǎn)品咨詢、品牌設(shè)計、技術(shù)研發(fā)等領(lǐng)域
訪問 www.talkmoney.cn 了解更多
萬能說明書 | 早起日記Lite | 凹凸壁紙 | 言財
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/72598.html
摘要:權(quán)限控制業(yè)務需求查看用戶列表接口管理員才能使用更新用戶信息接口當前對應用戶才能調(diào)用這時候需要需要加入中間件來實現(xiàn)權(quán)限控制這時候咱們需要學習了解下課前學習了解入門教程基于的認證版實現(xiàn)本文中使用了插件現(xiàn)將服務邏輯代碼附上服務配置設(shè)置創(chuàng) 權(quán)限控制 業(yè)務需求:查看用戶列表接口(管理員才能使用)、更新用戶信息接口(當前對應用戶才能調(diào)用) 這時候需要需要加入中間件來實現(xiàn)權(quán)限控制: showImg(...
摘要:開發(fā)一個完整博客流程前言前段時間剛把自己的個人網(wǎng)站寫完,于是這段時間因為事情不是太多,便整理了一下,寫了個簡易版的博客系統(tǒng)服務端用的是框架進行開發(fā)技術(shù)棧目錄結(jié)構(gòu)講解的配置文件放置代碼文件項目參數(shù)配置的文件日志打印文件項目依賴模塊 Vue + Node + Mongodb 開發(fā)一個完整博客流程 前言 前段時間剛把自己的個人網(wǎng)站寫完, 于是這段時間因為事情不是太多,便整理了一下,寫了個簡易...
摘要:自己在前后端分離上的實踐要想實現(xiàn)完整的前后端分離,安全這塊是繞不開的,這個系統(tǒng)主要功能就是動態(tài)管理,這次實踐包含兩個模塊基于搭建的權(quán)限管理系統(tǒng)后臺編寫的前端管理。 自己在前后端分離上的實踐 要想實現(xiàn)完整的前后端分離,安全這塊是繞不開的,這個系統(tǒng)主要功能就是動態(tài)restful api管理,這次實踐包含兩個模塊,基于springBoot + shiro搭建的權(quán)限管理系統(tǒng)后臺bootshir...
摘要:自己在前后端分離上的實踐要想實現(xiàn)完整的前后端分離,安全這塊是繞不開的,這個系統(tǒng)主要功能就是動態(tài)管理,這次實踐包含兩個模塊基于搭建的權(quán)限管理系統(tǒng)后臺編寫的前端管理。 自己在前后端分離上的實踐 要想實現(xiàn)完整的前后端分離,安全這塊是繞不開的,這個系統(tǒng)主要功能就是動態(tài)restful api管理,這次實踐包含兩個模塊,基于springBoot + shiro搭建的權(quán)限管理系統(tǒng)后臺bootshir...
閱讀 1765·2021-09-22 15:10
閱讀 1261·2021-09-07 09:58
閱讀 2333·2019-08-30 15:44
閱讀 1635·2019-08-26 18:29
閱讀 2033·2019-08-26 13:35
閱讀 759·2019-08-26 13:31
閱讀 720·2019-08-26 11:42
閱讀 1065·2019-08-23 18:39