nginx的auth_request模块,如何改写401状态码默认行为?
发布于 作者:苏南大叔 来源:程序如此灵动~

本文描述的nginx
的auth_request
模块的一个简单的小用法,可以在一个现有的系统外部,凭空增加一层全局验证,并且对系统原有代码做到零侵入。这个方法可是听起来有点小厉害的。本文中,仅仅实现了改写部分,并没有实现具体的用户名密码验证逻辑。也就是说:本文仅仅实现了登录框的拦路,并没有实现用户名密码的验证的细节,光拦截了没有通过的细节部分。

苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验文章。本文测试环境:win10
,nginx@1.15.11
,php@8.2.1
。
nginx
配置
这个nginx
的配置,仅仅是为了更容易地说明本文的问题,而进行的配置最简化。实际的配置,会更加复杂。参考的原版配置,来自这里:

本文没有贴出auth
这个站点的nginx
配置,就是最简单的.php
的配置,可以参考苏南大叔的其它文章。比如:

auth/check.php
这里实际上应该完成cookie
为基础的逻辑验证,但是这里并没有实现,因为这个不是本文的重点。这里的逻辑是:只要验证失败,就要发出401
状态码。然后再由nginx
的error_page 401
进行转写。
重点就是401
状态码的发出,就代表着验证不通过。

nginx拦截401代码
nginx
通过auth_request
模块进行鉴权拦截,所以请确保auth_request
模块已经被正确编译。可以通过下面的命令来进行确认。
正确的输出里面会有auth_request
的字样。

使用方式是:
上面的代码就是说,本来全部请求都要转向proxy_pass http://backend/
的,但是这里加入了一个auth_request /check
权限检测。/check
呢实际上也是个代理的页面,如果它验证不通过就会发出401
状态码。这个时候,就会被error_page 401
所拦截。强制把鉴权方式改成传统的表单模式。
backend
这个是个upstream
的设置,这并不在本文的讨论范围之内。
auth/login.php
这个逻辑就是非常简单,就放了一个传统的表单。

参考文章
实际效果就是如截图所示。如果没有强制的改写,则是浏览器跳出鉴权对话框。如果被强制代码转写后,就变成了普通可自定义的登录框。本文实际上参考了nginx
官方的一个项目,地址如下:
原版的是用python
完成的验证和表单逻辑,不过存在着一些小的问题,待后续讨论。
结束语
苏南大叔的更多nginx
相关文章,请点击:


