nginx 使用 openRestry 版本
在配置文件中设置
# 路径加密 文件
location ^~/group/ {
access_by_lua '
-- 获取请求路径,不包括参数。例如:/group/456.png
local uri = ngx.var.uri;
-- 获取请求参数
local args = ngx.req.get_uri_args();
-- 获取请求参数中时间戳信息,传入的是毫秒
local ts = args["ts"];
-- 获取请求参数中 token 信息
local token1 = args["token"];
-- 更新系统缓存时间戳
ngx.update_time();
-- 获取当前服务器系统时间,ngx.time() 获取的是秒
local getTime = ngx.time() * 1000;
-- 计算时间差
local diffTime = tonumber(ts) - getTime;
-- md5 加盐加密
local token2 = ngx.md5(tostring(uri) .. "salt" .. tostring(ts));
-- 判断时间是否有效
if (tonumber(diffTime) > 0) then
-- 校验 token 是否相等
if token1 == token2 then
-- 校验通过则转发请求
ngx.exec("@fastDFS");
end
end
';
}
# 使用 lua 脚本 进行路径判断
# 获取当前系统时间,并返回 ###
location /getTime {
default_type text/html;
content_by_lua '
ngx.say(ngx.time() * 1000);
';
}
以上为nginx.conf 中配置的信息
java 生成对应的url token
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import org.junit.Test;
import org.springframework.util.DigestUtils;
/**
* @description 生成带有效期与 token 的 URL 测试
* @author HochenChong
* @date 2018-7-15
* @version 0.1
*/
public class NginxTest {
@Test
public void test() {
// 获取 Nginx 服务器上的系统时间
String requestUrl = "http://localhost/getTime";
long systemTime = Long.parseLong(getURLContent(requestUrl));
System.out.println("Nginx 服务器上系统时间:" + systemTime);
// 请求的资源路径
String requestResources = "/group/234.jpg";
String url = getUrl(requestResources, systemTime);
System.out.println("请求的 url 为:");
System.out.println("192.168.229.165 /" + url);
}
/**
* 获取带时间戳与 token 的 url
* @param requestResources 请求的资源路径,不包括 IP 地址与端口,开头有 /,例如 /group1/M00/00/00/wKjlpltF-K-AZQQsAABhhboA1Kk469.png
* @param systemTime 系统时间
* @return 返回请求的 url 地址,包括有效期与 token
*/
public static String getUrl(String requestResources, long systemTime) {
// 添加有效期时间,假设该链接有效期为 1 天,即 86400000
// 计算毫秒时,切记转换为 Long 类型进行运算,避免超出 int 类型的范围
// 有效期,单位:毫秒
// 自己测试时,为了方便,可以设置为 1 分钟之类的
long milliseconds = systemTime + 1L * 24 * 60 * 60 * 1000;
// long milliseconds = systemTime + 60L * 1000;
// 计算 token 信息
// “盐” 值,和 Nginx 服务器上的保持一致即可
String salt = "salt";
// 加密前的字符串:请求的资源路径 + “盐” 值 + 时间戳
String beforeEncryptionString = requestResources + salt + milliseconds;
// 这里使用 Spring 提供的 md5 加密工具进行 md5 加密
String token = DigestUtils.md5DigestAsHex(beforeEncryptionString.getBytes());
String url = requestResources + "?ts=" + milliseconds + "&token=" + token;
return url;
}
/**
* 获取请求 url 返回的文本
* @param requestUrl 请求的 url
* @return
*/
public static String getURLContent(String requestUrl) {
URL url = null;
BufferedReader in = null;
StringBuffer sb = new StringBuffer();
try {
url = new URL(requestUrl);
in = new BufferedReader(new InputStreamReader(url.openStream()));
String str = null;
while ((str = in.readLine()) != null) {
sb.append(str);
}
} catch (Exception e) {
e.printStackTrace();
} finally{
// 关闭资源
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
}