基于Koa搭建Node接口转发项目(一)

本文介绍了如何使用Node.js和Koa框架搭建一个服务进行接口转发,解决了跨域问题,并实现了JWT鉴权。通过项目初始化、安装依赖、创建路由、设置静态资源访问以及添加登录接口,构建了一个基础的Node服务。此外,还涉及了异常处理和token的生成与验证。
摘要由CSDN通过智能技术生成

接口通过Node转发在实际开发中存在很多好处,比如接口安全性、解决跨域、统一数据规范等,接下来简单分享给大家如何搭建一个Node服务进行接口转发,下图为项目结构截图
在这里插入图片描述

具体过程如下:

1、创建一个项目并进行项目初始化

// 创建一个项目
sudo mkdir -v [project name]
// 初始化项目
npm init -y


// package.json的scripts添加代码如下(需全局安装 nodemon)
"scripts": {
 "dev": "nodemon index.js"
},

2、安装依赖koa、koa-body、koa-jwt、koa-logger、koa-router、koa-views、swig

yarn add koa // 主要核心依赖
yarn add koa-body // 处理请求体,用于文件上传配置
yarn add koa-jwt // token生成
yarn add koa-logger // 控制台打印日志
yarn add koa-router // 路由控制
yarn add koa-view swig // 视图控制

3、根目录创建一个index.js文件,使用koa创建一个服务,引入控koa-logger和koa-body中间件,跑起一个简单的服务。

const path = require('path');
const Koa = require('koa’);
const { koaBody } = require('koa-body');
const logger = require('koa-logger');

const app = new Koa();
const PORT =7001;

// 控制台日志
app.use(logger());
// 文件上传需要,更多配置参考koa-body文档
app.use(koaBody({multipart: true}));
app.listen(PORT);
console.log('Server listen in:' + PORT);

4、添加路由,创建一个视图
(1)创建一个routers文件夹,其下创建一个index.js文件,代码如下:

const router = require('koa-router')();

// 页面访问
router.get('/(.*)', async function (ctx) {
 await ctx.render('index', {
  title: '测试项目',
  env: process.env.CONFIG_ENV
 });
});

module.exports = router;

(2)根目录index文件引入路由配置文件和视图配置

const views = require('koa-views');
const router = require('./routers');
// 模板
app.use(views(path.join(__dirname, './template'), { map: {html: 'swig'}}));
//路由
app.use(router.routes());

(3)创建template文件夹,创建一个index.html文件,作为主页被访问

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8" />
	<meta http-equiv="X-UA-Compatible" content="IE=edge" />
	<meta name="viewport" content="width=device-width, initial-scale=1.0" />
	<title>{{title}}</title>
</head>
<body>
 	Hello World!
</div>
</body>
</html>

4)运行yarn dev 发现可以正常访问一个页面

5、添加静态资源访问路径
(1)创建一个public目录,其目录下创建一个static目录存放静态文件
(2)根目录index.js引入静态资源中间件,其中有两种方式,其一是直接使用koa-static,其二是自己写一个中间件。

// 可以通过引入koa-static实现,但是只能配置单个目录,不方便
const koaStatic = require("koa-static");
app.use(koaStatic(__dirname +/public/static"));

/*———————-----------------------------——————————*/

// 采用自己书写中间件方式实现资源访问,过程如下:
//(1)创建一个middleware目录,创建一个static文件
//(2)安装koa-send用于处理静态文件访问,minimatch用于对路径匹配,具体代码如下:
const send = require('koa-send');
const minimatch = require('minimatch');

const CACHE_STATIC_PATH = {};

const matchFilePath = (match, path) => {

	if(CACHE_STATIC_PATH[path]) return path;

	const type = typeof match;

	switch(type) {
		case 'string':
			if(minimatch(path, match)) {
				CACHE_STATIC_PATH[path] = 1;
				return path;
			}
		break;
		case 'object':
			for(let i = 0, length = match.length; i < length; i++) {
				if(minimatch(path, match[i])){
					CACHE_STATIC_PATH[path] = 1;
					return path;
				}
			}
		break;
default: break;
}
return false;
}

module.exports = function static(match, options) {
	return async (ctx, next) => {
		const curUrl = ctx.path;
		let fileUrl = matchFilePath(match, curUrl);

		if (!fileUrl) {
			return await next();
		}
		await send(ctx, curUrl, { root: options.dir, maxage: options.maxage });
	}
}

//(3)引入中间件(可以同时配置多个路径为静态文件被访问)
const middles = require('./middleware');
app.use(middles.static([ '/static/js/*', '/static/css/*'],{
	dir: __dirname + '/public',
	maxage: 60 * 60 * 1000
}))

6、添加jwt鉴权校验
(1)根目录index.js添加代码如下:(代码放在前面,第一个处理的中间件,用于对异常的捕获)

// 异常捕获处理
app.use((ctx, next) => {
	return next().then(() => {
		const token = ctx.cookies.get('token');
		if (token) {
			ctx.cookies.set('token', token, { httpOnly: true, overwrite: true, maxAge: 12 * 3600 * 1000 });
		}
	}).catch(err => {
		// 验证
		if(err.status === 401) {
			ctx.status = 401;
			ctx.body = '没有权限,请登'
		} else {
			throw err;
		}
	})
})

(2)根目录index.js添加jwt校验中间件

// 密钥,这个参数对加密解密很重要,需要保证其安全性
const JWT_SECRET='shared-secret';

// jwt鉴权
app.use(jwt({
	secret: JWT_SECRET,
	cookie: 'token',
	getToken: (ctx) => ctx.request.query.token, // 如果地址栏有token,优先取地址栏的token进行校验
}).unless({ // 不需要走校验的路径
	path: [/^\/public/, /\/api/login/]
}));

(3)创建一个utils文件,其下创建一个token_utils.js文件,主要进行token生成和解密,代码如下:

const fs = require('fs');
const jwt = require('jsonwebtoken');

// 需要和中间件校验的jwt_secret保持一致,可以用一个constant进行维护访问
const JWT_SECRET='shared-secret';

module.exports = {
// 解析token
parseToken(token) {
	try {
		return jwt.verify(token, JWT_SECRET);
	} catch (e) {
		return false;
	}
},
// 生成token
generateToken(user, exp) {
	if (!user) return null;

	!exp && (exp = Math.floor(Date.now() / 1000) + (30 * 60));// 默认30min
	return jwt.sign({
		exp,
		sub: user,
		iat: Math.floor(Date.now() / 1000) - 30, // 向前追溯30s
	}, JWT_SECRET)
}
}

(4)运行项目进行访问,发现报错“没有权限,请登陆”
(5)routers创建登陆接口路由,用于向浏览器cookie写入token,具体代码如下:

const { generateToken } = require('../utils/token_utils');

router.get('/api/login', async function(ctx){
	const { name: username } = ctx.request.query || {};
	if(!username) {
		ctx.body = { code: -1, msg: '请传入name参数'}
		return;
	}
	const token = generateToken(username);
	ctx.cookies.set('token', token, { httpOnly: true, overwrite: true, maxAge: 12 * 3600 * 1000 });
	ctx.redirect('/');
	})
})

(6)访问地址进行登陆http://localhost:7001/api/login?name=zhuqianyang(这里只是测试,实际登陆业务需更详细),发现跳转主页,登陆成功

测试项目github:https://github.com/reai99/create-node-server

这样就搭建了一个基本的Node服务了,这篇文章先分享到这里,接下来我会详细讲述如何封装接口形成配置进行接口转发。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值