博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NODE + JWT + Mongo(简单实现权限管理)
阅读量:6704 次
发布时间:2019-06-25

本文共 4682 字,大约阅读时间需要 15 分钟。

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

    • 输入错误的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开发团队

芦苇科技-广州专业软件外包服务公司

提供微信小程序、APP应用研发、UI设计等专业服务,专注于互联网产品咨询、品牌设计、技术研发等领域

访问 了解更多

万能说明书 | 早起日记Lite | 凹凸壁纸 | 言财

转载地址:http://fdblo.baihongyu.com/

你可能感兴趣的文章
将图片和文字写到pdf文件中
查看>>
如何用C++实现一个LRU Cache
查看>>
前端小白,了解这3点,不怕找不到工作!
查看>>
我的友情链接
查看>>
Android应用开发入门教程(经典版)
查看>>
sql查询分析器使用变量
查看>>
学.Net还是学Java?两者有什么区别?
查看>>
JVM致命错误日志(hs_err_pid.log)分析
查看>>
CentOS6.x系统下智能初始化脚本
查看>>
InRange 测试像素的值是否在给定范围内
查看>>
理解TCP/IP三次握手与四次挥手的正确姿势
查看>>
Hyper-V 2016 系列教程10 快照功能 检查点 和原还虚拟机
查看>>
用友U861产品登录时报:读取数据源出现未知错误:请检查IIS配置是否正确
查看>>
32004与重置参数
查看>>
1 创建安装用户
查看>>
Python魔法方法指南
查看>>
python 文件MD5 SHA1校验计算
查看>>
binlog
查看>>
acms性能调优跟踪
查看>>
调优指南:了解Linux性能指标
查看>>