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类型和签名算法,只做base64payload
: 保存一些不敏感用户信息,如用户名, 只做base64sign
: 签名,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服务器上部署:
- 前端打包
npm run build
生成打包目录dist, 把dist目录放入http服务器访问 npm i -g serve
http服务 也可使用nginx,见文章:https://blog.csdn.net/hhhmonkey/article/details/119333875serve dist
- 后端启动 先安装依赖
cnpm i
启动npm run start
- 代码上传ftp
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就跳转到对应的模块了