node:jwt、拦截器-学习笔记

本文介绍了Node.js项目中使用JWT进行权限验证的实现,包括JWT的生成与验证,以及利用nodemon实现代码修改后自动重启。同时,展示了如何设置HTTP拦截器来过滤无效请求,并探讨了项目部署时的hash和history模式选择,以及在Windows和Linux服务器上的部署步骤。
摘要由CSDN通过智能技术生成

node:jwt、拦截器

nodemon

  • 每次修改代码后都需要手动重启服务?
  • cnpm i -S nodemon
  • nodemon-每次保存时自动重启
  • nodemon main.js --exec babel-node 使用babel-node执行
  • npm run dev2
{
  "name": "0",
  "version": "1.0.0",
  "description": "",
  "main": "",
  "scripts": {
    "start": "babel-node main.js",
    "dev": "cross-env PORT=4000 babel-node main.js",
    "dev2": "nodemon main.js --exec babel-node"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "babel-cli": "^6.26.0",
    "babel-node": "^0.0.1-security",
    "babel-plugin-add-module-exports": "^1.0.2",
    "babel-preset-env": "^1.7.0",
    "body-parser": "^1.19.0",
    "cross-env": "^7.0.2",
    "express": "^4.17.1",
    "jsonwebtoken": "^8.5.1",
    "mysql2": "^2.1.0",
    "nodemon": "^2.0.4",
    "sequelize": "^5.22.2",
    "winston": "^3.3.2"
  }
}

jwt

  • 比如钥匙
  • 其中第一段为 header(头),第二段为 payload (负载),第三段为signature(签名)
  • header: 定义token类型和签名算法,只做base64
  • payload: 保存一些不敏感用户信息,如用户名, 只做base64
  • sign: 签名,header+payload+secret(加盐) 一起签名算法加密 生成加密字符串
  • secret:相当于自己私有的钥匙(很长的字符串64) secret在服务端(私有)
  • 以上知道jwt如何生成, 验证jwt是不是有效(通过secret解密)
  • cnpm i -S jsonwebtoken
  • 服务端一旦生成jwt token,只能等待它过期

util/constan.js用于放常量

const constant = {
    secret: "xxxdfsdfsdasdfsdfsdf"  //盐
}

export default constant

user.ctrl.js

//用户控制器 操作用户的接口
import jwt from 'jsonwebtoken'
import constant from '../util/constant'
import logger from '../util/logger'
import * as userService from '../service/user.service'

const operations = {
    //生成token
    generateToken(data){
        return jwt.sign(data, constant.secret, {
            expiresIn: '60000' //ms 1d---1天
        })
    },
    // 用户登录接口
    login: function(req, res){
        let {account, password} = req.body;
        logger.info("调用用户登录接口开始"+account+" "+password)
        userService.findUser(account, password)
        .then(data=> {
            if(data){
                //data中不能有密码
                let result = {
                    data:data,
                    msg: "用户登录成功"
                }
                let jwt = operations.generateToken(result);
                result.token = jwt;
                res.status(200).json(result)
                logger.info("用户登录成功")
            }else{
                res.status(400).json({"msg":"用户登录失败"})
                logger.info("用户登录失败")
            }
        })
    },  
}

export default operations

拦截器

  • 作用:过滤过无效请求,包括没有jwt,无效的jwt等

my.route.js:

//路由
import jwt from 'jsonwebtoken'
import constant from '../util/constant'
import express from 'express'
import userCtrl from '../controllers/user.ctrl'
import logger from '../util/logger';

const router = express.Router(); //使用express框架自带的路由 类比vue-router

export default function(app){
    //控制器接口--需要路由  接口请求方式(get post)
    //接口定义请求方式: get post delete put
    //用户        路由地址     请求方式   控制器接口
    router.route('/user/list-page').post(userCtrl.listPage);
    router.route('/user/create').post(userCtrl.createUser);
    router.route('/user/update').post(userCtrl.updateUser);
    router.route('/user/delete/:id').post(userCtrl.deleteUser);
    router.route('/user/query').get(userCtrl.query);
    router.route('/user/list').get(userCtrl.list);
    router.route('/user/login').post(userCtrl.login);// /api/user/login

    //权限
    let checkPermission = (req, res, next)=>{
        logger.info("权限检查。。。")
        //若是跨域请求  首先会有一个试探请求 OPTIONS
        if (req.method === 'OPTIONS'){
            res.send({"msg":"ok"})
        } else if (req.originalUrl === '/api/user/login'){//登录不限制
            next();
        } else if (req.headers.hasOwnProperty('token')){
            //验证token
            logger.info("token 验证", req.headers.token)
            //验证 合法  有效
            jwt.verify(req.headers.token, constant.secret, function(err, decoded){
                if (err) {
                    //logger.error(err); //无效  刚过期(刷新token)
                    if (err.name === 'TokenExpiredError') { //过期
                        logger.error('token过期');
                        // 得到过期时间  若半小时以内 可以刷新token 即不需要重登录
                        let time = ((new Date().getTime()-err.expiredAt.getTime())/(1000*60)).toFixed(2)
                        if (time<=30){
                            logger.info('生成新的token返回前端'); //与登录一样 前端要用新token
                            //根据code返回新token, 前端拿到新token再次发请求
                            res.send({"code":"10001", "token":"xxxxxx"});
                        }
                    }else if (err.name === 'JsonWebTokenError'){
                        logger.error('token无效');
                    }

                } else {
                    logger.info(JSON.stringify(decoded))
                    req.user = decoded; //将解密的数据保存在user属性中
                    next();
                }
            })
        } else {
            logger.info("没有token,无效请求")
            res.send({"msg":"没有token,无效请求"})
        }
    }
    app.use(checkPermission)

    //合同

    //把路由配置在myexpress实例上
    app.use('/api', router);
}

项目部署-hash

windows服务器上部署:

linux服务器:

  • 代码上传ftp+xshell xshell可以在终端上上传文件 yum install
  • 用xhell连接服务器
  • 启动后端 先安装依赖 要创建一个sh文件 添加命令:nohup npm run start & 在后端永久运行
    在这里插入图片描述
    在这里插入图片描述
  • 添加执行权限 sudo chmod +x start.sh
    在这里插入图片描述
    查看是否启动,用搜索语句grep
    在这里插入图片描述
  • 前端部署 解压dist目录,创建一个sh文件 文件内容: nohup serve dist & 前端若要修改端口可查看npm官网的serve文档
  • 服务器还需要开放端口

常用命令
ls 显示当前目录内容
cd 切换目录
ps 查看进程
vim 编辑文本
搜索进程:ps -ef|grep node

项目部署-history

在这里插入图片描述

  • 打包npm run build
  • 安装插件connect-history-api-fallback
  • 在myexpress.js中配置插件
app.use(history());
app.use(express.static(path.join(__dirname, '../dist'))); //指定页面位置

在这里插入图片描述

  • 只需要启动一个服务即可 npm run start
  • 原理: http://localhost:5003/loan-input/index—重定向http://localhost:5003/—
    系统检查到loan-input/index就跳转到对应的模块了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值