使用nginx+lua进行token鉴权的方法
作者:逸丶时光
使用nginx和lua脚本实现对Minio服务器图片链接的token鉴权,通过反向代理隐藏真实IP,增强安全性,介绍了整个鉴权流程,包括nginx配置和lua脚本的具体实现,适用于需要保护图片不被未授权访问的场景
最近在使用minio文件服务器,来实现图片上传与展示功能,在展示的时候出现一个问题,就是图片在做鉴权时,minio提供的有效地址是真的拉跨,没法实现图片链接的有效鉴权功能,而且链接直接给出来的话也有风险。
后面想着加一个反向代理的方式,也就是Nginx做代理,这样就不会暴露图片的ip地址。但是,在做鉴权时遇到了麻烦,网络上大部分推荐lua脚本来实现鉴权的方式,在经过几天的不断试错,才最终将他实现,现在在此记录下。
工具:openresty(nginx集成lua模块,比较简单)
lua包需要下载lua-resty-http工具包,地址lua-resty-http,解压后将.lua文件放到 lualib\resty目录下就行。
实现思路:用户发送请求---> nginx ----->根据图片路径策略-----> 执行lua代码(发送http到后端token鉴权)----->通过就代理到具体图片服务器----->否则提示无权限
nginx关键代码
http { # 定义全局变量 init_by_lua_block { cjson = require "cjson"; http = require "resty.http"; } server { location ~^/(api)/image/(.*)$ { rewrite_by_lua_block { -- local cjson = require "cjson" -- local http = require "resty.http" local httpc = http.new() local ngx = ngx local headers = ngx.req.get_headers() -- get请求参数中T就是token local token = headers["token"] local request_method = ngx.var.request_method local args = nil if "GET" == request_method then args = ngx.req.get_uri_args() elseif "POST" == request_method then ngx.req.read_body() args = ngx.req.get_post_args() end token = args["token"]; if not token then ngx.header['Content-Type'] = 'text/plain; charset=utf-8'; ngx.status = ngx.HTTP_FORBIDDEN ngx.say("您无权限浏览该图片。") ngx.exit(200) end -- 字符串拼接 -- 你要实现token鉴权的服务,header和参数都给你实现了,根据实际需要选择 local url = "http://127.0.0.1:8080/image/checkToken?token="..token; local res, err = httpc:request_uri(url, {method="GET", headers={["token"]=token}}) if not res then ngx.header['Content-Type'] = 'text/plain; charset=utf-8'; ngx.say(cjson.encode({message = "Error getting response",status = ngx.HTTP_INTERNAL_SERVER_ERROR })); ngx.exit(200) end if res.body == '0' then ngx.header['Content-Type'] = 'text/plain; charset=utf-8'; ngx.say("您无权限浏览该图片。"); ngx.exit(200) end } proxy_pass http://yourip:9000/$2; } } }
Java后端代码
@RestController @RequestMapping("/image") public class TokenResource { @RequestMapping("/checkToken") public String checkToken(HttpServletRequest request, String token) { System.out.println("程序进来了"); String header = request.getHeader("token"); System.out.println("头部token:" + header); if (StringUtils.isEmpty(token)) { System.out.println(token + ":0"); return "0"; } if ("1".equals(token)) { System.out.println(token + ":1"); return "1"; } return "0"; } }
当token校验通过,就不做拦截,lua代码执行完会走到nginx的转发路径上来
proxy_pass http://your_ip:9000/$2
~^/(api)/image/(.*)$ 写成 ~^/api/image/(.*)$ 时 proxy_pass 改为 http://your_ip:9000/$1
到此这篇关于使用nginx+lua进行token鉴权的方法的文章就介绍到这了,更多相关nginx lua token鉴权内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!