Nodejs + Expressjs+ JWT,JWT使用

来源:互联网 发布:知乎提示浏览器版本低 编辑:程序博客网 时间:2024/04/30 09:30

为什么要用研究JWT呢,一次关于用户token传递到讨论中,研发部的同事提到 SpringCloud 的zuul网关中引入 JWT,底层服务进行无状态处理,来实现我们之前关于token 传递的技术需求。

JWT(JSON Web Token),字面意思很好理解,就是Web的JSON令牌。一种通过Web可以安全传递JSON格式信息的机制。优势体量小,防串改,数据相对安全。可以用于客户端到服务器端重要用户数据保持,验证用户签名数据,也可以用于无状态服务的状态保持。(个人粗略理解),而我们项目要做的事情,就是用户登录后把用户当前操作的企业关系,以及用户id存储起来。通过网关将JWT解密后,有相关业务权限的API调用都是使用JWT中传递过来的参数进行权限校验。也可以参考JWT简介或者官方网站jwt.io

本人对SpringCloud zuul 网关的认知还是有限,于是就用Nodejs 对JWT进行了实践.本文参照这篇文章实践的。

首先是环境我使用的是expressjs+jsonwebtoken 还有一些类库morgan ,mongoose,body-parser ,测试代码包依赖如下

{"dependencies": {    "body-parser": "^1.17.2",    "express": "^4.15.3",    "express-jwt": "^5.3.0",    "jsonwebtoken": "^7.4.1",    "mongoose": "^4.10.4",    "morgan": "^1.8.2" }}

会用Nodejs的,安装这些估计都没有问题。

写一个配置文件 config.js

module.exports = {    'network' : {    'port':8080  },      'jwtsecret': 'myjwttest',  'database': '你的mongo库链接或者其他'};

实现简单的配置,然后是mongo数据库操作对象文件 user.js 返回User表对象

var mongoose = require('mongoose');var Schema = mongoose.Schema;// 返回一个mongo用户库实例module.exports = mongoose.model('User', new Schema({     name: String,     password: String,     admin: Boolean   //要不要都行}));

下来是写我们的主逻辑 index.js

1.引用

var express     = require('express');var app         = express();var bodyParser  = require('body-parser');var morgan      = require('morgan');var mongoose    = require('mongoose');var jwt    = require('jsonwebtoken'); // 使用jwt签名var config = require('./config'); // 引入配置var User   = require('./user'); // 获得mongo用户库实例

2.基础应用开启

// mongo数据库设置   mongoose.connect(config.database);    // 设置superSecret 全局参数   app.set('superSecret', config.jwtsecret);    // 使用 body parser 将post参数及URL参数可以通过 req.body或req.query 拿到请求参数   app.use(bodyParser.urlencoded({ extended: false }));   app.use(bodyParser.json());   // 使用 morgan 将请求日志输出到控制台   app.use(morgan('dev'));   //根路径处理结果   app.get('/', function(req, res) {res.send('JWT 授权访问的API路径 http://localhost:' + config.network.port + '/api');   });   //开启服务app.listen(config.network.port);console.log('JWT测试服务已经开启地址: http://localhost:' + config.network.port);

开启一个初始化express app 并开启一个express 应用。

3.用户数据写入

// 在steup 路径下简单用户数据写入操作,为了身份验证,当然也可以不使用数据库。app.post('/setup', function(req, res) {    if(req.body.name && req.body.password){          var nick = new User({         name: req.body.name,         password: req.body.password,        admin:req.body.admin||false          });         nick.save(function(err) {         if (err) throw err;        console.log('用户存储成功');        res.json({ success: true });  });}  else{      res.json({ success: false,msg:"错误参数" });  }});

简单写入

4.获取授权Token

// 用户授权路径,返回JWT 的 Token 验证用户名密码app.post('/authenticate', function(req, res) {    User.findOne({        name: req.body.name     }, function(err, user) {        if (err) throw err;        if (!user) {          res.json({ success: false, message: '未找到授权用户' });        } else if (user) {           if (user.password != req.body.password) {            res.json({ success: false, message: '用户密码错误' });          } else {        var token = jwt.sign(user, app.get('superSecret'), {              expiresIn : 60*60*24// 授权时效24小时        });        res.json({              success: true,              message: '请使用您的授权码',              token: token        });      }       }    });});

到了这一步,已经可以拿到jwt 的token 了,然后就可以通过token访问到下面要设定的API路径了。

5.API路由处理 拦截验证JWT

//  localhost:端口号/api 路径路由定义var apiRoutes = express.Router();apiRoutes.use(function(req, res, next) {    // 拿取token 数据 按照自己传递方式写    var token = req.body.token || req.query.token || req.headers['x-access-token'];    if (token) {              // 解码 token (验证 secret 和检查有效期(exp))        jwt.verify(token, app.get('superSecret'), function(err, decoded) {                    if (err) {            return res.json({ success: false, message: '无效的token.' });                  } else {                // 如果验证通过,在req中写入解密结果                req.decoded = decoded;                  //console.log(decoded)  ;                next(); //继续下一步路由          }        });      } else {        // 没有拿到token 返回错误         return res.status(403).send({             success: false,             message: '没有找到token.'         });      }    });

6.JWT验证后操作

//API跟路径返回内容apiRoutes.get('/', function(req, res) {  res.json({ message: req.decoded._doc.name+'  欢迎使用API' });});//获取所有用户数据apiRoutes.get('/users', function(req, res) {  User.find({}, function(err, users) {res.json(users);  });});   // 注册API路由app.use('/api', apiRoutes);

7.运行node应用

node index

8.Postman测试

添加用户

获取授权token

使用token 访问徐权限API

无token

错误token

api/users 访问结果

如果有需要通过nodejs 了解jwt 的可以访问源代码github



源地址(请尊重原创)

请使用手机"扫一扫"x