网关提供了什么?
- 统一登录
- 反向代理
- web服务器
- 接口拦截
以上是我根据项目需求已经实现了的功能,后续还可以扩展一些其他功能: 灰色发布等。
背景
开发环境时防止跨域会在webpack中添加proxyTable配置,这个配置只在开发环境生效。等到了生产环境会单独启一个Express服务提供web静态资源和proxyTable。
也就是说,每个应用都会有一个Express服务,当应用多了以后不利于管理,部署麻烦。
至于为什么不用Nginx,别问我,咱也不知道- . -
因为生产环境都是经理来部署的,然后他就嫌这个太麻烦,于是就提出要做一个网关。
我是如何实现的
egg服务的中间件
cors Middleware
egg-cors插件内置中间件,该中间件用于支持处理跨域请求一个请求解析的过程
static Middleware
egg-static插件内置中间件,该中间件用于对外提供静态资源
multiApplicationStatic Middleware
egg-multi-application-static针对多应用映射不同的静态资源路径。使用koa-static插件实现,并将封装为插件
- prefix 域名
- dir 静态入口路径
源码解析
-
遍历配置项
-
取出来源域名与配置项的prefix对比
满足:则取出配置项的dir生成一个提供静态资源服务的中间件并返回。
不满足:返回next()
-
利用compose工具函数形成洋葱圈式的调用并返回
bodyParser Middleware
会解析请求体中的参数并添加到request对象中,当经过该插件解析后的请求再做proxy时可能会丢失post参数
,所以这里要过滤
一下:
如果访问路径是网关自己路由的话则解析,否则跳过
需要注意该中间件的顺序,当post请求被该中间件处理后,再做proxy可能会丢失参数
securities Middleware
egg-security预防与处理XSS(跨站脚本攻击)。
permissions Middleware
验证token及刷新token。
源码解析
- 有token
- 验证token是否有效,无效则返回401
- 请求路径为
/gateway/login
或/
时直接跳回refererS
地址或者提示已登录,refererS不存在
- 更新cookie.refererS有效时间
- 更新cookie.token有效时间
- 无token
- 来源域是否已注册,未注册则返回401
Application not register!
- 请求路径为
/gateway/login
时则设置cookie.refererS - 请求路径是否需要登录,需要则返回401
Request path not authorized!
- 来源域是否已注册,未注册则返回401
- 上面流程无return时则return next()函数
proxy Middleware
针对config.proxy
中配置的域名及路径进行反向代理。
先判断请求来源的域名是否在config.proxy中,若条件满足则取出该域名下的配置,配合http-proxy-middleware、koa-connect插件进行代理与响应。
一个请求解析的过程
- 进入multiApplicantionStatic中间件,判断是否为静态资源
- 进入 permissions中间件, 验证token是否合法
- 进入proxy中间件, 根据config的配置进行转发请求
- 交由egg-router处理
PS
大佬请轻喷, 直接从笔记里copy的,可能就我自己能看懂 - -。