Aliyun OSS Nginx proxy module (아 리 클 라 우 드 OSS Nginx 서명 에이전트 모듈)

15910 단어
1. 이 글 의 주요 소개 내용
본 고 는 주로 Nginx lua 를 이용 하여 아 리 클 라 우 드 OSS 저장 공간 을 로 컬 디스크 와 똑 같이 사용 하 는 방법 을 소개 한다.핵심 은 Nginx lua 를 이용 하여 OSS 요청 에 서명 하고 내부 전환 을 이용 하여 로 컬 Nginx 에 접근 하 는 모든 요청 에 OSS 서명 을 추가 하여 OSS 에 전송 하여 로 컬 Nginx 의 이음매 없 는 연결 을 실현 하 는 것 입 니 다. 아 리 클 라 우 드 OSS 는 저장 공간 이 무한 확장 되 고 저장 비용 이 무한 감소 하 며 데이터 안전% 99.99...
2. 본 글 에서 사용 하 는 도구 기술 및 학습 및 획득 방법
1、lua
본 고 는 모두 기본 적 인 lua 를 사용 하 는데 대체적으로 30 분 동안 lua 의 문법 을 읽 으 면 본 고의 내용 을 쉽게 이해 할 수 있다.
2、Nginx lua
주로 nginx lua 와 환경 배 치 를 배 우 는 것 이지 만 본 고 를 읽 을 때 nginx lua 환경 을 직접 배우 고 배치 할 필요 가 없다. 독 자 는 docker 공식 미 러 소스 pull openresty 미 러 에서 실험 할 수 있다.본 고 는 이미 openresty / 1.7.2 를 실험 환경 으로 삼 았 다.
3. 아 리 운 OSS
빨리 개통 하 세 요.https://www.aliyun.com/act/aliyun/ossdoc.html
4. 참고 블 로그
제 다른 블 로 그 를 읽 고 OSS 와 인터넷 에서 제공 하 는 HTTP 서 비 스 를 깊이 이해 하 는 데 더욱 깊 은 이 해 를 가 질 것 을 건의 합 니 다.http://blog.csdn.net/sunrain_chy/article/details/50804410
3. Nginx lua 를 이용 하여 서명 요청 및 OSS 로 전송
Lua 서명 코드 주석: 이 코드 는 작성 자의 손 에서 나 온 것 이 아 닙 니 다 ossauth.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'
}

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: 
   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] .. '
'
end return table.concat(keys) end local function calc_sign(key, method, md5, type_, date, oss_headers, resource) -- string_to_sign: -- method + '
' + content_md5 + '
' + content_type + '
'
-- + date + '
' + canonicalized_oss_headers + canonicalized_resource
local sign_str = string.format('%s
%s
%s
%s
%s%s'
, method, md5, type_, date, oss_headers, resource) ngx.log(ngx.ERR, "SignStr:", sign_str, "
"
) 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 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.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. 상기 코드 를 어떻게 사용 합 니까?
우선 ossauth. lua 는 변경 할 필요 가 없습니다.
nginx. conf 에서 youross_bucket 아 리 클 라 우 드 OSS 의 bucket 이름 youraccess_id 교체 미 AccessKeyId youraccess_key 를 AccessKeySecret 로 변경
예 를 들 면:
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;
        }
    }
}

좋은 웹페이지 즐겨찾기