BLOG / POST
Nginx 如何区分不同设备访问
通过 Nginx 识别用户代理,实现对特定设备(如苹果设备)的访问控制。
- nginx
- ops
今天接到一个用户的需求
他希望能够屏蔽公司的苹果设备访问一些web应用。当苹果设备访问应用时给出提示:苹果设备禁止访问。
这里补充下,我们给客户做了10多个web应用,并通过nginx代理到端口6100上,通过不同的路径访问不同的应用,nginx 配置大致如下:
server{
listen 6100;
server_name 127.0.0.1;
location /book {
root /data/nginx/html/app;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /bank {
root /data/nginx/html/app;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}
上述分别访问到 /data/nginx/html/app/book 和 /data/nginx/html/app/bank 目录下的静态资源。
通过前端代码处理
在静态资源入口,加上 user agent 的判断,区分类型返回不同的页面,大致代码如下:
const app = document.querySelector("#app")
const platform = navigator.platform || navigator.userAgentData.platform
// 判断是否是苹果设备
if (/mac|ipone|ipad/i.test(platform)){
app.innerHTML = "no permission"
}else {
app.innerHTML = "hello"
}
虽然说这种方法也可以实现当前需求,但是这里需要修改将近10个web应用,意味着这10多个应用的代码都得修改,所以在前端代码中作修改并不太合适。
通过Nginx做处理
nginx 作为网关,同样可以获取到用户访问设备的 user agent。因此在nginx上拦截是个不错的选择。具体处理如下:
map $http_user_agent $is_apple {
default 0;
"~*iphone|ipad|ipod|Mac" 1;
}
server{
listen 6100;
server_name 127.0.0.1;
location /no-permission {
root /hjxz/nginx/html/app;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /book {
if ($is_apple = 1){
return 307 /no-permission
}
if ($is_apple = 0){
root /hjxz/nginx/html/pc;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}
location /bank {
if ($is_apple = 1){
return 307 /no-permission
}
if ($is_apple = 0){
root /hjxz/nginx/html/pc;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}
}
- 定义
is_apple变量,用户判断设备访问的型号 - is_apple 变量默认值是0,当
"~*iphone|ipad|ipod|Mac" 1;当设备是苹果型号则返回1 - 添加一个
/no-permission路径的映射,里面的静态文件内容是一个显示「没有权限」的html 文件 - 当
is_apple的值等于1时,重定向到/no-permission路径。
完。