Nginx 图片缩放私有地址实现教程

1. 整体流程

下面是实现 "Nginx 图片缩放私有地址" 的整体流程:

步骤 描述
1 客户端请求缩放后的图片
2 Nginx 接收到请求
3 Nginx 验证请求的合法性
4 Nginx 使用 Lua 脚本生成缩放后的图片
5 Nginx 返回缩放后的图片给客户端

2. 详细步骤

2.1 验证请求合法性

首先,我们需要验证客户端的请求是否合法。为了实现私有地址,我们可以在客户端请求中添加签名参数,通过签名来验证请求的合法性。

下面是验证请求合法性的代码:

location /resize-image {
    set $secret_key "YOUR_SECRET_KEY";  # 设置私钥
    
    if ($arg_signature != md5($secret_key.$arg_image_url.$arg_width.$arg_height)) {
        return 403;  # 验证失败,返回 403 Forbidden
    }
}

解释:

  • $secret_key 是我们设置的私钥,用于生成签名。
  • if 语句用于判断请求中的签名是否与服务器计算的签名一致。如果不一致,则返回 403 Forbidden

2.2 使用 Lua 脚本生成缩放后的图片

接下来,我们使用 Lua 脚本来生成缩放后的图片。Nginx 提供了 ngx.location.capture 函数来访问内部的子请求。

下面是生成缩放后的图片的代码:

location /resize-image {
    ...
    
    content_by_lua_block {
        local image_url = ngx.var.arg_image_url
        local width = ngx.var.arg_width
        local height = ngx.var.arg_height
        
        -- 调用内部子请求获取原始图片
        local res = ngx.location.capture("/get-image", {
            method = ngx.HTTP_GET,
            args = { url = image_url }
        })
        
        -- 调用 Lua 图形处理库对原始图片进行缩放
        local image = gm.Image(res.body)
        image:resize(width, height)
        
        -- 输出缩放后的图片
        ngx.header["Content-Type"] = "image/jpeg"
        ngx.print(image:toBlob())
    }
}

解释:

  • content_by_lua_block 指令用于执行 Lua 脚本。
  • ngx.location.capture 函数用于发起内部子请求,获取原始图片。
  • gm.Image 是一个 Lua 图形处理库,可以使用它来对图片进行缩放。
  • image:resize 方法用于调整图片的大小。
  • ngx.header["Content-Type"] 设置响应头的内容类型为 image/jpeg
  • ngx.print 用于输出缩放后的图片。

2.3 获取原始图片

为了实现私有地址,我们需要保护原始图片的真实地址,不直接暴露给客户端。我们可以使用 Nginx 的 internal 指令来限制只能通过内部子请求来访问获取原始图片。

下面是获取原始图片的代码:

location /get-image {
    internal;  # 限制只能通过内部子请求来访问
    
    proxy_pass $arg_url;
}

解释:

  • internal 指令用于限制只能通过内部子请求来访问。
  • proxy_pass 指令用于代理请求到指定的 URL,这里使用 $arg_url 获取客户端请求中的 url 参数作为代理地址。

3. 状态图

下面是一个状态图,展示了整个流程的状态转换:

stateDiagram
    [*] --> 客户端请求缩放后的图片
    客户端请求缩放后的图片 --> Nginx 接收到请求
    Nginx 接收到请求 --> Nginx 验证请求的合法性
    Nginx 验证请求的合法性 --> Nginx 使用 Lua 脚本生成缩放后的图片
    Nginx 使用 Lua 脚本生成缩放后的图片 --> Nginx 返回缩放后的图片给客户端
    Nginx 返回缩放后的图片