创建项目
- 使用生成器创建项目,不带视图引擎的项目话后面加上--no-view
express myapp --git
2. 初始化git
cd my-app
git init
3. 启动项目
npm install 或者 yarn
npm start 或者 yarn start
查看端口号
// 在www文件中增加
server.listen(port, () => {
console.log(`App listening at http://localhost:${port}`);
});
启用热更新
安装 nodemon
npm install --save-dev nodemon
或者 yarn add nodemon
修改 package.json
"start": "nodemon ./bin/www"
路由
在routers下面放的是路由,使用res.send({a:1})可以向前端发送任何数据
在js文件中,从上向下开始执行,next是执行下一个函数,如果传参了回到下一个函数的第一个参数中
router.get('/', function(req, res, next) {
res.send({a:1})
});
使用mysql2+ 连接池 连接数据库
安装mysql2
yarn add mysql2
创建连接池
const mysql = require('mysql2');
// 创建连接池,设置连接池的参数
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'root',
database: 'mydb',
connectionLimit: 10,
});
const promisePool = pool.promise();
module.exports = promisePool
//把这个文件引入到www文件就可以了
增,删,改,查
//增
router.post('/add', async function(req, res, next ) {
const { name, age,password } = req.body;
const [result] = await pool.query('INSERT INTO mytable (name, age,password) VALUES (?, ?,?)', [name, age,password]);
res.send(result);
})
//删
router.post('/delete', async function(req, res, next ) {
const { id } = req.body;
const [result] = await pool.query('DELETE FROM mytable WHERE id =?', [id]);
res.send(result);
})
//改
router.post('/modify', async function(req, res, next ) {
const { name, age,id } = req.body;
const [result] = await pool.query('UPDATE mytable SET name = ?, age = ? WHERE id = ?', [name, age, id]);
res.send(result);
})
//查
router.get('/', async function(req, res, next) {
const [data] = await pool.query('select * from mytable')
res.send(data);
});
使用(JWT)jsonwebtoken实现token登录
安装jsonwebtoken
yarn add jsonwebtoken
1. 封装JWT文件
const jwt = require('jsonwebtoken');
// 加密token的秘钥,任意值
const secretOrPrivateKey = 'nas8y9n32s'
const newJwt={
/**
*
* @param {*} value 要加密的值
* @param {*} time 过期时间
*/
creat:(value,time='10s')=>{
return jwt.sign(value,secretOrPrivateKey,{expiresIn:time})
},
/**
*
* @param {*} token 要解密的token
* @returns 返回解析后的值,里面包括创建的时候传的value,和过期时间。如果出错了或过期返回false
*/
verify:(token)=>{
try {
return jwt.verify(token,secretOrPrivateKey)
} catch (error) {
return false;
}
}
}
module.exports = newJwt
2. 在登陆接口向前端返回头中增加token
router.post("/login", async function (req, res, next) {
const { username, password } = req.body;
const query = `SELECT * FROM mytable WHERE name = ? AND password = ? ;`;
const [data] = await pool.query(query, [username,password]);
// 用户名和密码匹配的话设置token
if (data?.length) {
// 1.生成token
const token = jwt.creat({username, password});
//2/ 设置tokenn
res.header('Authorization',token );
res.send({
success:true
});
} else {
res.send({
success:false
});
}
});
3. 前端对接口统一处理,拿到token存储到localStorage,并且每次请求都带上token给后端去做验证
// 这个文件要在mian.js里引入才会执行 import './utils/axios.js'
import { Message } from '@alifd/next';
import axios from 'axios'
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
const token = localStorage.getItem('token')
config.headers.Authorization = token;
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
const {authorization} = response.headers
authorization && localStorage.setItem('token', authorization)
return response;
}, function (error) {
// 超出 2xx 范围的状态码都会触发该函数。
// 后端会设置状态码为401
// 跳转登录页面
Message.error('重新登录')
setTimeout(function () {
history.go(0);
},1000)
return Promise.reject(error);
});
4. 后端做路由拦截,校验token,要过滤掉登录和注册接口
//app.js
// 要放在所有路由的前面
// 路由拦截,校验token
app.use((req, res, next) => {
// 过滤登录接口
if (req.url === "/login") {
next();
return;
}
// 从headers中拿token
const token = req.headers["authorization"];
// 解析token
const paload = jwt.verify(token || '');
// 重新生成token
if (token && paload) {
const {username, password} = paload
const newToken = jwt.creat({username, password})
// 重新设置token
res.header('Authorization',newToken );
next();
}else{
// 返回错误
res.status(401);
res.send({
success:false,
message:'token失效'
});
}
});