老夫万万没想到,几年前无意间学了 NJS ,最近竟然用上了。
是的你没看错,如果你会写javascript
,你甚至已经是一名Nginx
配置管理员。
今天我们就通过一个例子,带大家初步浅入门 NJS
。
前置知识:
- 一点点 nginx.conf 的认识
- javascript基本语法
- 其他作为程序员的基本素质
0x00 场景介绍(纯杜撰)
案件的经过是这样的,最近有一个新的后端项目,希望接入到我们已有的微服务集群里。
然后我好像明白了一些事情:
Python 开发效率第一条:不做复杂的事情。
不过既然阿刚硬刚,恰好我有解决的方案,就不妨接受挑战吧。
首先梳理一下原始需求:
- 真实的业务接口部署在我们的集群里
- 真实的业务接口需要做用户鉴权,如:判断用户是否登录
- 真实的业务接口不希望请求外部接口,希望网关放进来的都是已经登录的
如果做到了以上三点,他们确实可以很轻松,这理由很“充分”。
所以我指定了这个方案:
好了交代完背景我们进入很干的正题
NJS 真是一个好东西,我们平时看到的 Nginx.conf
,最多就做做反向代理、负载均衡。
现在告诉你,通过 javascript
还能给Nginx
赋能一些逻辑,一众 JSer
自然是很兴奋。
🤡 Nginx 高手竟在我身边。
那么我们看看怎么做:
// auth.js
function auth(r) {
r.subrequest('/auth') // 假设我们原本需要调用这个接口来检查登录
.then((reply) => {
if (reply.status !== 200) {
throw '未登录';
}
}).then(() => {
r.subrequest(r.uri, {})
// 隐去了一些不必要的细节
}).catch(e => {
r.return(401, e);
});
}
export default { auth };
直接贴代码,我觉得我也很刚。
上面这段简单的 JS
代码,相信大家也能看明白的大概。
意思就是,当请求进来时,首先去内部请求一下 /auth
接口;
如果返回的不是200,就告诉前端 401 未登录
;
否则,再发起内部请求到真实业务接口 r.uri
,得到真正的业务接口返回数据。
编写完JS逻辑,这事还没完,需要在 Nginx.conf 里增加点东西
// nginx.conf (只贴关键内容)
# 配置文件开头:载入 NJS 模块
load_module modules/ngx_http_js_module.so;
...
...
http {
# 通过 js_import 引入上面的JS代码
js_import main from auth.js;
...
...
server {
...
...
location ~ ^/ {
# 所有请求都通过上面的JS代码来处理了
js_content main.auth;
}
🔥🔥🔥因为上面的分解动作,都是在 Nginx 内部转发完成的,所以在前端的感受上就只是发生了一次简单的请求。
而对于躲在背后的业务接口来说,
开发接口的时候不需要关心用户鉴权,直接裸奔上阵。