access阶段是用于控制请求是否可以继续向下访问。
一、access模块
access模块是一个很简单的模块,是用于控制哪些IP可以访问某些url,哪些ip不可以访问某些url。模块名是ngx_http_access_module,默认是被编译进nginx中的,可以使用--without-http_access_module进行禁用
access模块提供两条指令:
- allow:允许哪些地址可以访问某些url。
- deny:禁止哪些地址可以访问某些url。
这两条指令可以出现在http、location、server、limit_except上下文中。
设置deny之后,access阶段之前的阶段还是会被执行。
当一个location中配置了多条allow或者deny,例如:
location / {
allow 1.1.1.1;
deny 2.2.2.2;
allow 3.3.3.3;
.....
}
当匹配到第一条时,后面的就不会执行,如果没有匹配到第一条,则会向下匹配。
二、auth_basic模块
auth_basic模块是可以对用户名密码做限制,进行校验的模块。
auth_basic模块默认是编译进nginx中的(Openresty默认没有编译),可以使用--without-http_auth_basic_module进行禁用。
1、HTTP Basic Authentication
HTTP Basic Authentication鉴权的过程:
客户端访问nginx时,nginx会返回一个401响应,并且响应体中有一个WWW-Authenticate字段,浏览器在接收到该响应之后,就会弹出一个要求输入账号密码的弹出框,输入提交之后,浏览器就会讲我们输入的账号密码存在Credentials字段中,以明文的方式发送给nginx,所以这里传输数据很不安全,使用HTTPS加密之后就安全了。
2、auth_basic指令
auth_basic指令值为string或者off,默认为off。string即为弹出框的title。可以出现的上下文为http、location、server、limit_except。
3、auth_basic_user_file
该指令的值为一个文件地址,该文件是一个存储user:password的文件,可以存储多个。
三、auth_request模块
auth_request模块默认是没有被编译到nginx中的,需要使用--with-http_auth_request_module方法进行添加编译。
1、原理
当nginx接收到客户端请求之后,会生成一个子请求,并通过反向代理技术发送给上游服务器,上游服务器处理之后,返回响应。如果返回的状态码是2xx,则继续执行,如果是401或者403,则返回给客户端。
2、指令
-
auth_request:默认是关闭的,值可以为url,nginx会生成一个子请求,然后去匹配location模块。
-
auth_request_set:为变量设置值,使用:auth_request_set $val value
3、案例
本地启动两个nginx项目,一个是nginx-demo,一个是nginx-demo1。
nginx-demo的配置:
upstream local {
server 127.0.0.1:3000;
}
server {
listen 8000;
server_name localhost;
server_name_in_redirect on;
error_page 404 /50x.html;
error_log logs/error.log info;
location / {
auth_request /test;
}
location = /test {
proxy_pass http://local;
proxy_pass_request_body off;
proxy_set_header Content_Length '';
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
解释:当请求http://localhost:8000/时,nginx会产生一个字请求:http://localhost:8000/test,该子请求匹配到locaion = /test {....}模块,并代理到http://local,即nginx-demo1的nginx上。
nginx-demo1的配置:
server {
listen 127.0.0.1:3000;
server_name localhost;
location /test {
return 401 '401';
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
解释:nginx-demo1的nginx接收到来自nginx-demo的子请求,匹配到location /test模块,并返回401,nginx-demo在接收到该返回之后,将该子请求的结果发送给客户端,客户端显示结果如下:
如果nginx-demo1的location /test模块中return的为200,那么它会返回html/index.html文件,即使这里没有配置root和try_files。
四、satisfy指令
satisfy指令允许我们改变模块的执行顺序。
1、使用
satisfy指令的值只能是all或者any。上下文为http、server、location中。
access阶段有多个模块,当satisfy设置为all时,access阶段的所有模块都通过之后,才会向下执行,任何一个模块拒绝之后,就会返给客户端4xx或者5xx错误;当satisfy设置为deny时,access阶段的任意模块通过之后,就会向下执行。
五、一个access模块执行过程
执行过程:
-
当执行access阶段时,先判断access模块的allow或者deny有没有设置。
-
当allow或者deny都没有设置,则认为忽略该模块,继续向下执行下一个模块。
-
当请求放行之后,判断satisfy指令的值,如果为any,则access阶段的任何一个模块通过,就向下执行下一个阶段。如果为all,则需要access阶段的所有模块都通过,才会向下执行下一个阶段。
-
当请求被拒绝之后,判断satisfy指令的值,如果为any,则向下执行下一个模块,如果为all,则直接拒绝请求,不再向下执行。
六、问题
1、如果有return指令,access阶段还会执行吗?
答:不会,return指令存在server rewrite和rewrite阶段,在access之前,所以一旦执行return,就会向用户返回响应,不会再向下执行。