1、此文章主要介绍内容

本文主要介绍如何利用Nginx lua 实现将阿里云OSS存储空间做到同本地磁盘一样使用。核心是利用Nginx lua 对OSS请求进行签名并利用内部跳转将所有访问本地Nginx的请求加上OSS 签名转发给OSS,实现本地Nginx无缝衔接阿里云OSS,存储空间无限扩展,存储成本无限下降,数据安全%99.99...... 。

2、本篇文章使用到的一些工具技术及如何学习和获取

1、lua

本文用到的都是一些基本的lua,基本上花半小时阅读下lua的语法就可以轻松理解本文内容

2、Nginx lua

主要是学习nginx lua 及环境部署,不过阅读本文还不需要亲自动手去学习及部署nginx lua 环境,读者可以从docker 官方镜像源pull openresty 镜像进行实验。本文已openresty/1.7.7.2 作为实验环境。

3、阿里云OSS

赶紧开通吧,用起来相当爽,一处存储全球无限制访问

https://www.aliyun.com/act/aliyun/ossdoc.html

4、参考博客

建议阅读我的另外一篇博客,对深入理解OSS 及互联网上提供的HTTP服务有更深刻的理解

https://yq.aliyun.com/articles/7511?spm=0.0.0.0.IWbHSR

3、利用Nginx lua 实现请求签名并转发至OSS

Lua 签名 code

注:此代码并非出自作者之手

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'
} 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
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;
}
}

、如何使用上述代码

首先oss_auth.lua 无需做任何改动

nginx.conf 中需要将

your_oss_bucket 替换为阿里云OSS 的bucket名

your_access_id替换未AccessKeyId

your_access_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 "za2127hbbdsdjhkhskel0ytocbzr";
set $oss_auth_key "gMOG3o+JHDSJHCNMcsaH+Q=";
rewrite_by_lua_file conf/lua/oss_auth.lua;
} location @oss {
proxy_pass http://bucket-example.oss-cn-qingdao.aliyuncs.com;
}
}
}

Aliyun OSS Nginx proxy module(阿里云OSS Nginx 签名代理模块)的更多相关文章

  1. 第2-3-1章 文件存储服务系统-nginx/fastDFS/minio/阿里云oss/七牛云oss

    目录 文件存储服务 1. 需求背景 2. 核心功能 3. 存储策略 3.1 本地存储 3.2 FastDFS存储 3.3 云存储 3.4 minio 4. 技术设计 文件存储服务 全套代码及资料全部完 ...

  2. SpringBoot整合阿里云OSS文件上传、下载、查看、删除

    1. 开发前准备 1.1 前置知识 java基础以及SpringBoot简单基础知识即可. 1.2 环境参数 开发工具:IDEA 基础环境:Maven+JDK8 所用技术:SpringBoot.lom ...

  3. 小白的springboot之路(十七)、阿里云OSS 的使用

    0-前言 项目中,文件服务必不可少,常用的有各云服务商的OSS服务(如阿里云OSS,腾讯云OSS,七牛云).自建(fastDFS.minio): 推荐:如果用云服务的话,阿里云OSS很方便,如果自建的 ...

  4. Springboot项目之阿里云OSS快速入门

    阿里云oss 阿里云对象存储服务(Object Storage Service,简称OSS),是阿里云对外提供的海量.安全.低成本.高可靠的云存储服务.您可以通过本文档提供的简单的REST接口,在任何 ...

  5. 保姆级SpringBoot+Vue图片上传到阿里云OSS教程

    小二是新来的实习生,作为技术 leader,我给他安排了一个非常简单的练手任务,把前端 markdown 编辑器里上传的图片保存到服务器端,结果他真的就把图片直接保存到了服务器上,这下可把我气坏了,就 ...

  6. 用DzzOffice管理阿里云OSS

    在DzzOffice分两种方式管理阿里云OSS 1.把阿里云oss作为多人或企业的共享网盘使用. 2.接入个人的阿里云oss管理,可同时管理多个bucket,多个bucket之间可以互传文件. 下面先 ...

  7. laravel使用阿里云OSS上传图片

    需要自己注册阿里云账号并且开通oss服务,建立Bucket存储空间,此步骤不做演示 一.composer安装:使用composer在项目根目录执行以下命令 composer require johnl ...

  8. ECS上nginx搭建反向代理通过内网访问阿里云OSS服务

    对于付不起钱的小伙计,为了给公司省钱,想尽一切招数.今天就来分享一个使用阿里云OSS存储搭配CDN使用的网站服务器部署方法. 简介 阿里云OSS 阿里云提供的一种文件存储方案,和我们以前接触的百度云B ...

  9. PHP上传文件到阿里云OSS,nginx代理访问

    1. 阿里云OSS创建存储空间Bucket(读写权限为:公共读) 2. 拿到相关配置 accessKeyId:********* accessKeySecret:********* endpoint: ...

随机推荐

  1. UOJ#218. 【UNR #1】火车管理 线段树 主席树

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ218.html 题解 如果我们可以知道每次弹出栈之后新的栈顶是什么,那么我们就可以在一棵区间覆盖.区间求和 ...

  2. Konva入门教程

    啥是 Konva Konva 是一个 canvas 库,可以让我们像操作 DOM 一样来操作 canvas,并提供了对 canvas 中元素的事件机制,拖放操作的支持.所以,用它来做一个拼图游戏什么的 ...

  3. WebSocket的Tomcat实现

    一.WebSocket简单介绍 随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了.近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通 ...

  4. Windows的四类消息

    Windows的三类消息1.标准消息宏名称 对映消息 消息处理函数(名称已由系统预设)ON_WM_CHAR WM_CAHR OnCharON_WM_CLOSE WM_CLOSE OnCloseON_W ...

  5. java生成/解析二维码

    package a; import java.awt.BasicStroke; import java.awt.Graphics; import java.awt.Graphics2D; import ...

  6. 6、echarts使用的坑

    实例化id值要用唯一的,一个项目中不能用同一个id, 不然后面的样式覆盖前面的,且后面样式不显示.

  7. Oracle 触发器 trigger

    触发器: 当用户登录/退出或者操作某个数据对象或者进行DDL(建表,建view)引起某个储存过程的值的变化,把这个隐含被调用的过程,称为触发器. 语法 CREATE OR REPLACE TRIGGE ...

  8. ARM_DMA学习

    AMBA: advanced(高级) microcontroller bus architecture; 利用多层总线系统减少DMA传输和CPU中断的延迟: DMA流或DMA通道,流优先级,Adres ...

  9. Spring Session event事件分析

    1. org.apache.catalina.session.StandardSession 这是servlet-api jar包中的一个类.是session接口的标准实现.当session创建的时候 ...

  10. JS数组循环的性能和效率分析(for、while、forEach、map、for of)

    从最简单的for循环说起 for( 初始化:条件; ){} 条件为Trusy 值时候,可以继续执行for 循环,当条件变为Falsy 时跳出for循环.for循环常见的四种写法const person ...