发布作者:
柒汐博客
作品采用:
《
署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)
》许可协议授权
secure_link机制简单来说就是来保护你的http资源被受控访问的,类似于防盗链、http授权访问的Token。假如你有一些私有化的、需验证身份才能访问的资源,就可以使用这个机制。
下面是一个简单的流程,分为两步
代码涉及两个部分,一个是nginx网关部分。另一部分则为核心的API。
代码使用Go语言,出入参非常简单。
注意:sign在全链路下是无状态的,也就是泄漏后依然会有风险,推荐expire时间设置为分钟级,过期后拒绝请求可再签来实现安全性。
package service
import (
"crypto/md5"
"encoding/base64"
"fmt"
"strings"
)
// GenerateSignature 生成URI访问签名
//
// 参数:
// uri - 请求的URI路径
// expire - 签名过期时间戳(秒)
// secret - 签名密钥
//
// 返回值:
// string - 生成的签名字符串
//
// 实现原理:
// 1. 按照Nginx兼容格式拼接expire、uri和secret
// 2. 对拼接字符串进行MD5哈希计算
// 3. 哈希结果进行Base64 URL编码并去除末尾等号
func GenerateSignature(uri string, expire int64, secret string) string {
// 严格匹配 Nginx 的字符串格式:${expire}${
//
//uri} ${secret}
raw := fmt.Sprintf("%d%s %s", expire, uri, secret)
hash := md5.Sum([]byte(raw))
// Base64 编码 + 替换特殊字符(与 Nginx 兼容)
return strings.TrimRight(
base64.URLEncoding.EncodeToString(hash[:]), "=",
)
}
nginx无需任何插件即可实现该功能,而且http_secure_link是nginx的worker内特性。还是无状态check,所以不存在太多的性能问题,不会拖慢nginx的响应速度。
secret 必须与 GenerateSignature 函数中的secret参数完全一致,否则无法过签名
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location /protected/ {
secure_link $arg_st,$arg_exp;
# secret 记得更换
secure_link_md5 "$arg_exp$uri secret";
if ($secure_link = "") {
return 403; # Bad hash
}
if ($secure_link = "0") {
return 410; # Expired
}
# 明确指定文件物理路径别名
alias /usr/share/nginx/static/;
}
location / {
root /usr/share/nginx/html;
index index.html;
}
}
}
该场景下可以实现部分api、static、html的保护访问,可以做到http访问保护。但是一定要注意时间问题,尽量保证泄露的风险最小。
本例如有demo、技术支持需求,欢迎在下面评论~
—— 评论区 ——