oss_auth.lua signed_subresources add'x -oss-process' to realize image processing
Added
1. This article mainly introduces the content
This article mainly introduces how to use Nginx lua to use Alibaba Cloud OSS storage space as a local disk. The core is to use Nginx lua to sign OSS requests and use internal jumps to forward all requests to access local Nginx plus OSS signatures to OSS, so that local Nginx can seamlessly connect to Alibaba Cloud OSS, unlimited storage space expansion, and unlimited storage costs. Data security%99.99…….
2. Some tools and techniques used in this article and how to learn and acquire
1 、 lua
This article uses some basic lua, basically spend half an hour reading the grammar of lua, you can easily understand the content of this article
2、Nginx lua
Mainly to learn nginx lua and environment deployment, but reading this article does not need to learn and deploy nginx lua environment by yourself, readers can pull openresty mirror from the official docker mirror source to experiment. This article has been openresty/1.7.7.2 as the experimental environment.
3. Alibaba Cloud OSS
Hurry up and activate it, it’s pretty cool to use, one store has unlimited global access
https://www.aliyun.com/act/aliyun/ossdoc.html
4. Reference blog
It is recommended to read another blog of mine to have a deeper understanding of OSS and HTTP services provided on the Internet
http://blog.csdn.net/sunrain_chy/article/details/50804410
3. Use Nginx lua to implement request signing and forward it to OSS
Lua signature code
Note: This code is not from the author
oss_auth.lua
-- has been sorted in alphabetical order
local signed_subresources = {
'acl',
'append',
'bucketInfo',
'cname',
'commitTransition',
'comp',
'cors',
'delete',
'lifecycle',
'location',
'logging',
'mime',
'notification',
'objectInfo',
'objectMeta',
'partData',
'partInfo',
'partNumber',
'policy',
'position',
'referer',
'replication',
'replicationLocation',
'replicationProgress',
'requestPayment',
'response-cache-control',
'response-content-disposition',
'response-content-encoding',
'response-content-language',
'response-content-type',
'response-expires',
'restore',
'security-token',
'tagging',
'torrent',
'uploadId',
'uploads',
'versionId',
'versioning',
'versions',
'website',
'x-oss-process'
}
function string.startswith(s, start)
return string.sub(s, 1, string.len(start)) == start
end
local function get_canon_sub_resource()
local args = ngx.req.get_uri_args()
-- lower keys
local keys = {}
for k, v in pairs(args) do
keys[k:lower()] = v
end
-- make resource string
local s = ''
local sep = '?'
for i, k in ipairs(signed_subresources) do
v = keys[k]
if v then
-- sub table
v = type(v) == 'table' and v[1] or v
s = s .. string.format("%s%s=%s", sep, k, v)
sep = '&'
end
end
return s
end
local function get_canon_resource()
resource = ''
object = ngx.unescape_uri(ngx.var.uri)
sub = get_canon_sub_resource()
return string.format("/%s%s%s", ngx.var.oss_bucket , object, sub)
end
local function get_canon_headers()
-- default: <lowerkey, value>
local headers = ngx.req.get_headers()
local keys = {}
for k, v in pairs(headers) do
if string.startswith(k, 'x-oss-') then
-- client must assemble the same header keys
if type(v) ~= 'string' then return nil end
table.insert(keys, k)
end
end
-- sorted in alphabetical order
table.sort(keys)
for i, key in ipairs(keys) do
keys[i] = key .. ':' .. headers[key] .. '\n'
end
return table.concat(keys)
end
local function calc_sign(key, method, md5, type_, date, oss_headers, resource)
-- string_to_sign:
-- method + '\n' + content_md5 + '\n' + content_type + '\n'
-- + date + '\n' + canonicalized_oss_headers + canonicalized_resource
local sign_str = string.format('%s\n%s\n%s\n%s\n%s%s',
method, md5, type_,
date, oss_headers, resource)
ngx.log(ngx.ERR, "SignStr:", sign_str, "\n")
local sign_result = ngx.encode_base64(ngx.hmac_sha1(key, sign_str))
return sign_result, sign_str
end
local function oss_auth()
-- ngx.log(ngx.INFO, 'auth')
--local method = ngx.var.request_method
local method = ngx.req.get_method()
local content_md5 = ngx.var.http_content_md5 or ''
local content_type = ngx.var.http_content_type or ''
-- get date
local date = ngx.var.http_x_oss_date or ngx.var.http_date or ''
if date == '' then
date = ngx.http_time(ngx.time())
-- ngx.log(ngx.INFO, 'Date:', date)
ngx.req.set_header('Date', date)
end
ngx.req.set_header('Date', ngx.http_time(ngx.time()))
local resource = get_canon_resource()
local canon_headers = get_canon_headers()
local sign_result, sign_str = calc_sign(ngx.var.oss_auth_key, method, content_md5,
content_type, date, canon_headers, resource)
-- ngx.log(ngx.INFO, 'sign string:', sign_str)
-- ngx.log(ngx.INFO, 'sign string len:', string.len(sign_str))
local auth = string.format("OSS %s:%s", ngx.var.oss_auth_id, sign_result)
ngx.req.set_header('Authorization', auth)
ngx.log(ngx.EMERG,"<-- end :" .. auth)
local headers = ngx.req.get_headers()
for k, v in pairs(headers) do
ngx.log(ngx.EMERG,"[key]:",k," [v:",v)
end
ngx.exec("@oss")
end
-- main
res = oss_auth()
if res then
ngx.exit(res)
end
nginx.conf
server {
listen 8000;
proxy_http_version 1.1;
proxy_buffering off;
proxy_request_buffering off;
location / {
set $oss_bucket "your_oss_bucket";
set $oss_auth_id "your_access_id";
set $oss_auth_key "your_access_key";
rewrite_by_lua_file "/path/oss_auth.lua";
}
# internal redirect
location @oss {
// endpoint eg: oss.aliyuncs.com
proxy_pass http://your_oss_bucket.endpoint;
}
}
4. How to use the above code
First of all, oss_auth.lua does not need to be changed.
In nginx.conf, you need to
replace your_oss_bucket with the bucket name of
Alibaba Cloud OSS your_access_id without
AccessKeyId and your_access_key with AccessKeySecret
E.g:
error_log logs/error.log debug;
events {
worker_connections 1024;
}
http {
include mime.types;
lua_package_path "/usr/servers/lualib/?.lua;";
lua_package_cpath "/usr/servers/lualib/?.so;";
server {
listen 80;
location / {
set $oss_bucket "bucket-example";
set $oss_auth_id "za2127hbbsdhjal0ytocbzr";
set $oss_auth_key "gMOG3o+HJdsgdHdpieCNMcsaH+Q=";
rewrite_by_lua_file conf/lua/oss_auth.lua;
}
location @oss {
proxy_pass http://bucket-example.oss-cn-qingdao.aliyuncs.com;
}
}
}
access