19、nginx中location语法
1. 概述
- 在实际应用中,权限控制的需求更加复杂。例如,对于网站下的img目录允许所有用户访问,但对于网站下的admin目录则仅允许管理员身份的用户访问。此时,仅靠
deny和allow这两个权限指令不能满足用户的需求,还需要使用location块来完成相关需求的匹配。
2.location语法
location [=|~| ~* | ^~] URI { .... } #语法类型1
location @name { .... } #语法类型2
- 在上述语法中
=、~、~*、^~、@都是location用于实现访问控制的前缀,且在使用时只能选择一种,当然也可以不设置前缀。
| 前缀 | 说明 |
|---|---|
= |
根据其后的指定模式进行精准匹配。例如,在访问时要与/html/aaa/index.html完全一致才会执行其后的指令块 |
~ |
使用正则表达式完成location的匹配,区分大小写 |
~* |
使用正则表达式完成location的匹配,不区分大小写 |
^~ |
不使用正则表达式,完成以指定模式开头的location匹配 |
@ |
用于定义一个location块,且该块不能被外部客户端所访问,只能被Nginx内部配置指令所访问 |
2.1 精准匹配
- 所谓精准匹配指的就是用户访问的URI与指定的URI完全一致的情况,才会执行其后的指令块,示例配置如下。
server {
listen 80;
server_name localhost;
root html;
index index.html index.htm;
location=/js {
allow 192.168.78.128;
}
location =/admin/auth{
allow 192.168.78.200;
}
deny all;
}
| URL | A用户响应结果(192.168.78.128) | B用户响应结果(192.168.78.200) |
|---|---|---|
http://192.168.78.3 |
403 Forbidden | 403 Forbidden |
http://192.168.78.3/js |
404 Not Found | 403 Forbidden |
http://192.168.78.3/admin/auth |
403 Forbidden | 404 Not Found |
http://192.168.78.3/admin |
403 Forbidden | 403 Forbidden |
符合匹配规则,网页显示
404 Not Found,不符合时显示403 Forbidden。
2.2 正则匹配
- Nginx配置文件中,多个正则 location之间按照正则location 在配置文件中的书写顺序进行匹配,且只要匹配成功就不会继续匹配后面定义的正则location。
location ~\.html$ {
allow all;
}
location ~^/aaa/.*\.html${
deny all;
}
| URL | 响应结果 |
|---|---|
http://192.168.78.3/test.html |
404 Not Found |
http://192.168.78.3/aaa/test.html |
404 Not Found |
当location中的URI与用户请求中以
.html为结尾的文件匹配上时,正则location停止了继续匹配,因此显示结果都为404 Not Found调换上述两个location代码块的编写顺序,再次访问
http://192.168.78.3/test.html结果依然为404 Not Found,而访问http://192.168.78.3/aaa/test.html的结果为403 Forbidden.正则location的编写顺序不同,则结果不同,且只有前面定义的正则location匹配不成功的情况下,才会继续匹配后面的正则location。
2.3 最大前缀匹配
- 由于location可以同时定义多个,当一个配置文件中同时出现多个location时,普通 location 之间遵循
最大前缀匹配原则。通俗地讲就是,匹配度最高的location 将会执行。
location /ng.test {
allow all;
}
location /ng.test/log {
deny all;
}
| URL | 响应结果 |
|---|---|
http://192.168.78.3/ng.test |
404 Not Found |
http://192.168.78.3/ng.test/log |
403 Forbidden |
http://192.168.78.3/ng.test/log/date |
403 Forbidden |
-
当最大前缀location与正则location同时存在时,如果正则 location 匹配成功,则不会执行最大前缀location。
location / { deny all; } location ~\.html$ { allow all; }
| URL | 响应结果 |
|---|---|
http://192.168.78.3 |
403 Forbidden |
http://192.168.78.3/notfound.html |
404 Not Found |
http://192.168.78.3/index.php |
403 Forbidden |
- location / {} 与location = / {}的区别
- location / {} 遵守普通 location的最大前缀匹配,由于任何 URI 都必然以
/根开头,所以对于一个URI,若配置文件中有更合适的匹配则会将其替代,否则返回location / {} 匹配到的结果,它相当于站点默认配置。- location = / {} 遵守的是精准匹配,也就是只能匹配该站点根目录,同时会禁止继续搜索正则 location ,效率比 location/ {} 要高。因此,若在开发中能确定精准匹配的情况,可以采用location = / {} 的方式,提升匹配效率。
2.4 禁用正则匹配
- 利用
=精准匹配或^~非正则匹配可以在正则匹配之前优先匹配,从而禁止执行原有的正则匹配。下面在server块中添加以下几条location匹配规则,具体如下。
location =/aaa/test.html {
allow all;
}
location ^~/ {
deny all;
}
location ~\.html${
allow all;
}
=用于精准匹配网站根目录下的/aaa/test.html^~用于非正则匹配网站根目录下的文件~用于正则匹配网站根目录下以.html为结尾的文件
| URL | 响应结果 |
|---|---|
http://192.168.78.3 |
403 Forbidden |
http://192.168.78.3/index.html |
403 Forbidden |
http://192.168.78.3/bbb/test.html |
403 Forbidden |
http://192.168.78.3/aaa/test.html |
404 Not Found |
在使用了
=或^~前缀时,普通 location 匹配后将不再执行正则 location的匹配。前缀
=和^~虽然都能阻止继续搜索正则 location ,不同的地方是它们遵循的规则不同,^~依然遵循最大前缀匹配规则,而=则严格按照精准匹配执行。因此,当多种类型的 location 匹配同时出现时,最终执行结果为=匹配优先于^~匹配,^~匹配优先于正则匹配,正则匹配优先于普通的最大前缀匹配。只要优先的location匹配成功,就不会执行其他的 location。