例: $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后。
但是直接访问 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
浏览器会下载文件
或 直接
所有人在外网都可以访问,不安全。不会经过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,这里我们不做介绍)。
需要重新编译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这张图片上。
————————————————
上面是把token加在url 后面 ?token=“xxx” ,这种方式 get方式。
探索前端图片如何携带token进行验证
vue中给img的src添加token