例: $arg_token 取的就是 uri?args 中 token=xxx 的部分
$arg_PARAMETER #这个变量包含GET请求中,如果有变量PARAMETER时的值。
$args #这个变量等于请求行中(GET请求)的参数,例如foo=123&bar=blahblah;
$binary_remote_addr #二进制的客户地址。
$body_bytes_sent #响应时送出的body字节数数量。即使连接中断,这个数据也是精确的。
$content_length #请求头中的Content-length字段。
$content_type #请求头中的Content-Type字段。
$cookie_COOKIE #cookie COOKIE变量的值
$document_root #当前请求在root指令中指定的值。
$document_uri #与$uri相同。
$host #请求主机头字段,否则为服务器名称。
$hostname #Set to the machine’s hostname as returned by gethostname
$http_HEADER
$is_args #如果有$args参数,这个变量等于”?”,否则等于”",空值。
$http_user_agent #客户端agent信息
$http_cookie #客户端cookie信息
$limit_rate #这个变量可以限制连接速率。
$query_string #与$args相同。
$request_body_file #客户端请求主体信息的临时文件名。
$request_method #客户端请求的动作,通常为GET或POST。
$remote_addr #客户端的IP地址。
$remote_port #客户端的端口。
$remote_user #已经经过Auth Basic Module验证的用户名。
$request_completion #如果请求结束,设置为OK. 当请求未结束或如果该请求不是请求链串的最后一个时,为空(Empty)。
$request_method #GET或POST
$request_filename #当前请求的文件路径,由root或alias指令与URI请求生成。
$request_uri #包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。不能修改。
$scheme #HTTP方法(如http,https)。
$server_protocol #请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
$server_addr #服务器地址,在完成一次系统调用后可以确定这个值。
$server_name #服务器名称:域名或IP 那部分。 // 例: set $auth_request_uri "http://$server_name:8090/system/user/auth?$args";
$server_port #请求到达服务器的端口号。
$uri #不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。该值有可能和$request_uri 不一致。$request_uri是浏览器发过来的值。该值是rewrite后的值。例如做了internal redirects后。
使用auth_request做权限控制
背景:生产环境对于图片使用 标签来显示图片,或使用 element-ui 的 标签进行图片预览;
但是直接访问 url: http://192.168.0.225:8002/file/20231011/%E7%B3%BB%E7%BB%9F%E7%AE%A1%E7%90%86%E5%B7%A5%E4%BD%9C%E7%AB%99_531011143641805.pdf
浏览器会下载文件
或 直接 <img src = http://192.168.0.225:8002/file/20231011/wu2_531011104758539.png"。
所有人在外网都可以访问,不安全。不会经过java 后端接口的 @SaCheckLogin 鉴权。
所以,要么不直接访问 ,而是通过后端接口返回。 要么在nginx 层加一个权限校验, lua 鉴权或 通过 nginx 自带的模块 --with-http_auth_request_module
为了省事,采用了 nginx的 模块方式:
所以,前端开发人员就需要在图片加载过程中携带验证的信息。如 token,用于身份验证、权限控制等方面。通过在图片的 URL 后面(get请求方式),或请求头中携带 token 信息,从而实现图片信息的安全传输。
同时 后端增加一个单纯的鉴权接口:
/system/user/auth
@SaCheckLogin
@GetMapping("/auth")
public String info() throws Exception {
try {
return LoginHelper.getUsername();
}catch (Exception e){
throw new Exception("用户未登录!"+e.getMessage());
}
}
浏览器访问图片链接,然后根据request中的token信息判断此用户是否登录态 若是则返回 response.setStatus(200)
若不是登录态,则400.
技术:采用Nginx自带的auth_request模块(网上也有一些其他的方法比如安装redis模块,在nginx里直接查询redis,这里我们不做介绍)。
开启auth_request
需要重新编译nginx源码,把auth_request加入到nginx中,(1.5.4以上,默认包含auth_request,需要编译的时候开启)
配置校验参数
log_format pro '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_referer" "$http_user_agent" $request_time req_body:"$request_body"'
'"$http_user_agent" "$http_x_forwarded_for"';
server {
listen 8002;
server_name 192.168.0.225 localhost api.ltkj.com;
# root /data/wwwroot/static.ltkj.com/project;
# 重定向到error401 时用
proxy_intercept_errors on;
#禁止访问的文件或目录
location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)
{
return 404;
}
// 处理文件
location ^~ /file/ {
# expires 30d;
set $auth_request_uri "http://$server_name:8090/system/user/auth?$args";
auth_request /auth;
auth_request_set $user $upstream_http_x_forwarded_user;
proxy_set_header X-Forwarded-User $user;
error_page 401 500 = /error401;
root /data/wwwroot/static.ltkj.com/project;
}
// 处理图片
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
# img 标签 header中设置 token方式 未成功,待测试
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
auth_request /auth;
error_page 401 500 = /error401;
auth_request_set $user $upstream_http_x_forwarded_user;
proxy_set_header X-Forwarded-User $user;
set $auth_request_uri "http://$server_name:8090/system/user/auth?$args";
root /data/wwwroot/static.ltkj.com/project;
}
location /auth {
# 表示该路径仅仅为nginx内部访问,一旦出了这个配置文件,则失效
internal;
# 自己系统的认证路径
# proxy_pass http://localhost:8090/system/user/auth;
proxy_pass $auth_request_uri ;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Original-URI $request_uri;
proxy_set_header X-Original-METHOD $request_method;
error_page 401 500 = /error401;
}
# 认证失败后的处理
location = /error401 {
# 强制浏览器不使用缓存,防止缓存带来的还能访问系统
# 如果认证失败,跳转到自己系统的登录页面
return 302 http://192.168.0.225:8001/index;
}
access_log /data/logs/nginx/project_manager/access.log pro;
error_log /data/logs/nginx/project_manager/error.log ;
}
灵魂代码!灵魂代码!灵魂代码!
set $auth_request_uri "http://192.168.0.225:8090/system/user/auth?$args";
我的项目需求是对图片做权限校验,图片展示是直接在img标签里面展示的,因此,没法做请求头的设置,需要在链接后面携带校验信息。如:http://127.0.0.1/api/image/123.jpg?token=xxx
这时候校验信息,而网上大部分是没有这段代码的
set $auth_request_uri "http://192.168.40.14:8080/image/auth?$query_string";
导致参数无法传递到r后端校验地址(如果是设置请求头里的,可以获取到)。
校验成功就将127.0.0.1/api/image/123.jpg?token=xxx转发到 minio地址:9000/123.jpg。
校验失败后台设置响应状态401或403,将转发到authError.png这张图片上。
测试url
- http://192.168.0.225:8002/pic/20230825/530825093805902100.jpg 跳转到登录页 or 首页
- http://192.168.0.225:8002/pic/20230825/530825093805902100.jpg?Authorization=Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOiJzeXNfdXNlcjoxIiwicm5TdHIiOiJ0dEtOdkE5VTNwQkllWmgxV1h5OUZETWVoUzZINk5MbCIsInVzZXJJZCI6MX0.6_FQyAqTrRsWR4HdhD2qmFeqAOrHJ6cVguCzaW2JlC0 成功预览
- http://192.168.0.225:8002/file/20231011/系统管理工作站_531011143641805.pdf
- http://192.168.0.225:8002/file/20231011/系统管理工作站_531011143641805.pdf?Authorization=Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOiJzeXNfdXNlcjoxIiwicm5TdHIiOiJ0dEtOdkE5VTNwQkllWmgxV1h5OUZETWVoUzZINk5MbCIsInVzZXJJZCI6MX0.6_FQyAqTrRsWR4HdhD2qmFeqAOrHJ6cVguCzaW2JlC0
————————————————
上面是把token加在url 后面 ?token=“xxx” ,这种方式 get方式。
下面 尝试入到 header中
探索前端图片如何携带token进行验证
vue中给img的src添加token
版权归原作者 令狐少侠2011 所有, 如有侵权,请联系我们删除。