前面已经创建了主服务器,但是为了实现跨域访问,还得写一个代理服务器(proxy server)
下面是代理服务器的创建步骤:
首先安装依赖:
cd proxyApp
npm i
npm i http-proxy-middleware --save //安装代理自动转发中间件
npm i request -- save
npm i request-promise -- save //手动转发需要用的
//再安装jwt依赖
npm i jsonwebtoken --save
npm i express-jwt --save
npm i crypto --save //验证jwt
1、首先在public文件夹中写入文档(HTML,css等)
2、改端口,在www中将端口改为代理服务器的端口,避免端口重复。
3、api自动转发,在代理服务器中的app.js中引入api
const proxy = require("http-proxy-middleware");
const options = {
target:'http://127.0.0.1:3000', //转发的端口地址
changeOrigion:true,
pathRewrite:{
'^api':'/', //是否重写路径,将'api'重写为 '/',这样子主服务器才接口才认识
}
}
app.use("/api",proxy(options));
但是切记,在引入api之前先将
app.use(logger('dev')); //负责控制台打印的中间件
app.use(express.static(path.join(__dirname, 'public')));
这段代码提到下面这段代码之前,因为静态资源不需要被代理
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
4、手动转发
由于我们的代理服务器是有很多业务需求需要自己实现的,比如jwt验证,md5数据加密等等,因此我们不可能把所有的请求都直接自动转发到主服务器,那么很多情况我们是需要进行手动转发的。
在代理服务器的service目录下创建login方法,手动将请求转发到3000端口,这样子就可以在转发之前做一些诸如加密等等的操作;
const rp = require("request-promise")
const login = async (user) => {
console.log('userservice:',user);
const options = {
method: 'POST',
uri: 'http://127.0.0.1:3000/users/login',
body: user,
json: true
}
const data = await rp(options)
console.log("result:",data);
return data
}
module.exports = { login }
然后路由接到请求,交给业务层开始启动业务,
var express = require('express');
var router = express.Router();
const userService = require("../service/userService")
router.post('/login',async function(req, res, next) {
const user = req.body;
const data = await userService.login(user);
console.log(data);
res.send(data);
});
module.exports = router;
//下面是加入加密和jwt后的
const rp = require("request-promise");
const jwt = require("jsonwebtoken");//拿到jwt
const { secretKey, md5, MD5_SUFFIX } = require("../util/salt");
const login = async (user) => {
console.log("123", user);
// return 'service login';
user.password = md5(MD5_SUFFIX+user.password);//对密码进行md5加密
const options = {
method: 'POST',
uri: require("../util/options").target+'/users/login',
body: user,
json: true
};
let data = await rp(options);//判断是否成功
if (data.isLogin){
const playload = {
username:user.username
};
let token = jwt.sign(
playload,
secretKey,
{
expiresIn:1000 //token的有效时间
}
)
const result = {
success:true,
message:"成功了",
token
}
return result;
}
}
const regist = async function (user) {
user.password = md5(MD5_SUFFIX + user.password);//对密码加密之后再去数据库对比
const options = {
method: 'POST',
uri: require("../util/options").target + '/users/regist',
body: user,
json: true
};
let data = await rp(options);//判断是否成功
console.log('regist service',data);
// return data;
return data;
}
module.exports = { login, regist };
//util/options
module.exports={
target: 'http://127.0.0.1:3001',
changeOrigion: true,
pathRewrite: { //重写路径
'^/api': '/',
}
}
//util/salt
const crypto = require('crypto');
module.exports = {
MD5_SUFFIX: 'Joey',
md5: (pwd) => {
let md5 = crypto.createHash('md5');//用来加密的,包含了MD5加密模块
return md5.update(pwd).digest('hex');
},
secretKey: 'Joey_key'
};
//util/jwt
const expressJwt = require("express-jwt");//做验证的模块
const {
secretKey
} = require('./salt');
const jwtAuth = expressJwt({
secret: secretKey,
credentialsRequired: true // false:不校验
}).unless({
path: ["/users/login", "/users/regist"]
});
module.exports = jwtAuth; // app.jsconstjwtAuth=require("./utils/jwt");