原理介绍
应用客户端每个请求都将向应用服务器申请预签名URL,该预签名URL有效期由应用服 务器管理。具体流程如图13-2。
图13-2 移动应用访问 OBS 数据流程
角色分析如下:
● 应用客户端:即最终用户手机上的APP,负责向应用服务器申请包含预签名的 URL,以及访问OBS完成数据上传或下载。
● 应用服务器:即提供该Android/iOS应用的开发者开发的APP后台服务,用于管理 凭证信息以及发放预签名URL。
● OBS:即华为云对象存储,负责处理移动应用的数据请求。
实现流程如下:
1. 移动应用客户端向应用服务器申请一个预签名的URL。
3. Android/iOS移动应用获取此URL,直接使用该URL操作数据,比如上传或者下载 操作。
– 自定义请求消息头,请参考对应操作的API文档。例如PUT上传,参考PUT上传API。
// 本次请求的桶的endpoint
String endPoint = "http://your-endpoint";
最佳实践 13 移动应用直传
// 替换为您的AK、SK
String ak = "*** Provide your Access Key ***";
String sk = "*** Provide your Secret Key ***";
// 创建ObsClient实例
ObsClient obsClient = new ObsClient(ak, sk, endPoint);
// 替换您的过期时间,单位是秒 long expireSeconds = 3600L;
// 替换成您对应的操作
TemporarySignatureRequest request = new TemporarySignatureRequest(HttpMethodEnum.PUT, expireSeconds);
// 替换为请求本次操作访问的桶名和对象名 request.setBucketName("bucketname");
request.setObjectKey("objectname");
TemporarySignatureResponse response = obsClient.createTemporarySignature(request);
// 成功返回预签名URL,如下打印URL信息 System.out.println(response.getSignedUrl());
更多相关介绍和示例代码,请参见使用URL进行授权访问。
步骤2 移动应用客户端使用获取到的预签名URL发送OBS请求。
public class Demo extends Activity
{ private static String bucketName = "my-obs-bucket-demo";
private static String objectKey = "my-obs-object-key-demo";
private static OkHttpClient httpClient;
private static StringBuffer sb;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sb = new StringBuffer();
/*
* Constructs a client instance with your account for accessing OBS */
httpClient = new OkHttpClient.Builder().followRedirects(false).retryOnConnectionFailure(false) .cache(null).build();
final TextView tv = (TextView)findViewById(R.id.tv);
tv.setText("Click to start test");
tv.setOnClickListener(new View.OnClickListener() {
class DownloadTask extends AsyncTask<Void, Void, String>
{
@Override
protected String doInBackground(Void... params) {
Request.Builder builder = new Request.Builder();
// 使用PUT请求上传对象 Request httpRequest =
builder.url(response.getSignedUrl()).put(RequestBody.create(MediaType.parse(contentType), "Hello OBS".getBytes("UTF-8"))).build();
protected void onPostExecute(String result) {
TextView tv = (TextView)findViewById(R.id.tv);
tv.setText(result);
tv.setOnClickListener(null);
tv.setMovementMethod(ScrollingMovementMethod.getInstance());
} } }
----结束
最佳实践 13 移动应用直传
相关参考
● Java SDK接口参考文档
● Java SDK依赖缺失和依赖冲突的解决方法
14 小程序直传 OBS
背景信息
微信小程序作为当下流行的移动应用,具有广泛的应用场景。如何通过微信小程序上 传文件至对象存储服务OBS成为了一个热点问题,本文将通过一个示例程序进行演 示。
注意事项
● 计算签名时依赖引用“crypto-js”及“js-base64”两个开源组件,因此需要在微 信小程序项目中设置使用NPM模块。
● 在微信小程序中进行编译时,如果在引入“crypto-js”包时出现“Maximum call stack size exceed”报错,请升级微信小程序开发客户端至最新版本。
● 上传过程中返回405时,请检查指定的endpoint是否为对应上传桶的桶域名。
操作步骤
步骤1 设置桶的跨域访问权限。
微信小程序基于BrowerJS进行开发,受同源安全策略的要求,不同域间的网站脚本和 内容如需交互,需要配置跨域资源共享(CORS)规范。华为云对象存储服务OBS支持 CORS规范,允许跨域访问OBS中的资源,具体配置步骤请参见配置跨域资源共享。
CORS规则配置项建议:
表14-1 CORS 规则
参数 说明 配置建议
允许的来
源 必选参数,指定允许的跨域请求的来 源,即允许来自该域名下的请求访问该 桶。
允许多条匹配规则,以回车换行为间 隔。每个匹配规则允许使用最多一个
“*”通配符。例如:
http://rds.example.com https://*.vbs.example.com
*
最佳实践 14 小程序直传 OBS
参数 说明 配置建议
● x-obs-request-id
● x-obs-api
● Content-Type
● Content-Length
● Cache-Control
● Content-Disposition
● Content-Encoding
● Content-Language
● Expires
● x-obs-id-2
● x-reserved-indicator
● x-obs-version-id
● x-obs-copy-source-version-id
● x-obs-storage-class
● x-obs-delete-marker
● x-obs-expiration
● x-obs-website-redirect-location
● x-obs-restore
● x-obs-version
● x-obs-object-type
● x-obs-next-append-position
微信小程序利用白名单机制管理跨域访问,想要实现数据上传,需要在微信小程序平 台域名白名单中配置桶的访问域名。
1. 获取桶的访问域名。
在桶列表单击待操作的桶,进入“概览”页面。在“基本信息”下查看桶的访问 域名。
2. 在微信小程序服务器域名配置中指定桶域名为合法域名。详细配置指导请在小程 序客服搜索“服务器域名配置”,配置信息如表14-2所示。
最佳实践 14 小程序直传 OBS
图14-1 微信小程序配置服务器信息
表14-2 微信小程序配置建议
参数 配置建议
request合法域名 桶的访问域名 socket合法域名 根据实际情况填写 uploadFile合法域名 桶的访问域名 downloadFile合法
域名
桶的访问域名
udp合法域名 根据实际情况填写 tcp合法域名 根据实际情况填写
步骤3 计算POST上传签名。
POST上传前需要根据上传时自定义使用的policy字段计算相关签名信息,签名计算规 则请参见基于浏览器上传的表单中携带签名,计算签名相关源代码如下:
对policy进行base64编码(GetPolicy.js):
const Base64 = require('js-base64');
function getPolicyEncode(policy) {
// 传入表单上传的policy字段,对policy进行Base64编码 const encodedPolicy = Base64.encode(JSON.stringify(policy));
return encodedPolicy;
}
module.exports = getPolicyEncode;
计算签名的源代码(GetSignature.js):
const Crypto = require('crypto-js');
const Base64 = require('js-base64');
function getSignature(policyEncoded, SecretKey){
// 利用SK对Base64编码后的policy结果进行HMAC-SHA1签名计算 const bytes = Crypto.HmacSHA1(policyEncoded, SecretKey);
// 对计算结果进行Base64编码,得到最终的签名信息 const signature = Crypto.enc.Base64.stringify(bytes);
return signature;
}
module.exports = getSignature;
步骤4 使用小程序直传数据至对象存储桶中。
基于步骤3中得到的编码后的policy字段及signature字段,可以调用小程序中的上传接 口,选择本地文件并上传。具体代码示例如下:
配置AK、SK、访问域名等信息的配置文件(Configuration.js):
● 使用永久访问秘钥(AK/SK)
// 指定OBS服务相关信息:AK,SK,EndPoint var Configuration = {
AccessKeyId: 'your access key ID', //AK SecretKey: 'your secret access key ID', //SK
EndPoint: 'https://your-test-bucket.obs.myhuaweicloud.com', //完整的桶访问域名 };
module.exports = Configuration;
● 使用临时访问秘钥(AK/SK/SecurityToken)
// 指定OBS服务相关信息:AK,SK,SecurityToken,EndPoint var Configuration = {
AccessKeyId: 'your access key ID', //AK SecretKey: 'your secret access key ID', //SK
Security_token: 'your Security Token', //SecurityToken
EndPoint: 'https://your-test-bucket.obs.myhuaweicloud.com', //完整的桶访问域名 };
module.exports = Configuration;
说明
配置文件中传入的EndPoint应该为完整的桶访问域名,例如:https://
bucketName.obs.myhuaweicloud.com,其中bucketName即小程序上传的目标桶名。
// 引入配置文件
const config = require('./Configuration.js');
// 引入policy编码计算方法
const getPolicyEncode = require('./getPolicy.js');
// 引入签名计算方法
const getSignature = require('./GetSignature.js');
const OBSupload = function (filePath){
if(!filePath){
wx.showToast({ 档 "expiration": "2021-12-31T12:00:00.000Z",
"conditions": [
{ "bucket": "your-test-bucket"}, // 桶名要和配置文件中endpoint中的桶名保持一致 { 'key': fileName}
最佳实践 14 小程序直传 OBS
] }
const policyEncoded = getPolicyEncode(OBSPolicy); // 计算base64编码后的policy const signature = getSignature(policyEncoded, config.SecretKey); // 计算signature wx.uploadFile({
url: config.EndPoint, filePath: filePath, name: 'file', header: {
'content-type': 'multipart/form-data; boundary=-9431149156168', },
module.exports = OBSupload;
----结束
相关操作
上传完成后,要获取对应对象的访问URL,请参见如何获取对象访问路径。
15 通过 Nginx 反向代理访问 OBS
背景
一般情况下,用户会通过OBS提供的桶访问域名(例如https://bucketname .obs.cn-north-4.myhuaweicloud.com)或者绑定的自定义域名来访问OBS。
但在某些场景下,用户需要通过固定的IP地址访问OBS,例如:某些企业出于安全考 虑,对于可访问的外部地址需要设置黑白名单,而这个时候对于OBS的访问则需要一 个固定的IP地址。同样出于安全考虑,华为云OBS桶访问域名通过DNS解析的IP地址是 会发生变化的,所以用户无法获取某个桶长期有效的固定IP地址。
此时,可以通过在ECS上搭建Nginx反向代理服务器,来实现通过固定IP地址访问 OBS。
原理介绍
本实践将Nginx部署在ECS上,搭建Nginx反向代理服务器。用户对代理无感知,只需 要将请求发送到反向代理服务器,然后由反向代理服务器向OBS获取数据,再返回给 用户。反向代理服务器和OBS对外看做一个整体,仅暴露代理服务器的IP地址,隐藏了 OBS真实的域名或IP地址。
最佳实践 15 通过 Nginx 反向代理访问 OBS
图15-1 通过 Nginx 反向代理访问 OBS 原理
前提条件
● 已明确OBS桶所在区域和桶的访问域名,如华北-北京四区域的桶:nginx-obs.obs.cn-north-4.myhuaweicloud.com。查看方法
● 已在同区域购买Linux操作系统的ECS,本文以CentOS系统为例。购买ECS方法
● ECS已绑定EIP,EIP用于从公网下载必要的Nginx安装包。
配置步骤
步骤1 在ECS上安装Nginx
1. 登录用于搭建Nginx反向代理服务器的ECS。
2. 使用wget命令,下载对应当前操作系统版本的Nginx安装包。此处以CentOS 7.6 版本的操作系统为例。
wget http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
3. 执行以下命令,建立Nginx的yum仓库。此处以CentOS 7.6版本的操作系统为例。
rpm -ivh nginx-release-centos-7-0.el7.ngx.noarch.rpm
4. 执行以下命令,安装Nginx。
yum -y install nginx
5. 执行以下命令,启动Nginx并设置开机启动。
systemctl start nginx systemctl enable nginx
6. 在任意终端使用浏览器访问“http://ECS弹性公网IP地址”,显示如下图所示,说 明Nginx安装成功。
图15-2 Nginx 安装成功
步骤2 修改Nginx配置文件,反向代理OBS桶
1. 执行以下命令,打开“default.conf”配置文件。
vim /etc/nginx/conf.d/default.conf
2. 按“i”键进入编辑模式,修改“default.conf”配置文件。
server {
listen 80;
server_name **.**.**.**; #此处填写ECS弹性公网IP地址 location / {
proxy_pass https://nginx-obs.obs.cn-north-4.myhuaweicloud.com; #此处填写OBS桶访问域名,
以http://或https://开头
server_name 提供反向代理服务的IP地址,即需要暴露给终端用户访问的固 定IP地址。
此处填写搭建Nginx反向代理服务的ECS弹性公网IP地址,即当 前登录的ECS弹性公网IP地址。
proxy_pass 被代理服务器的地址。
此处填写前提条件获取的OBS桶的访问域名,注意需要以 http://或https://开头,例如:
https://nginx-obs.obs.cn-north-4.myhuaweicloud.com
3. 按“Esc”,输入“:wq”保存并退出。
4. 执行以下命令,测试Nginx配置文件状态。
nginx -t
5. 执行以下命令,重启Nginx服务使配置生效。
systemctl stop nginx systemctl start nginx
步骤3 (可选)配置OBS桶策略,允许Nginx代理服务器的IP地址访问OBS
如果您的OBS桶为公共读,或者访问私有桶内对象时在URL中携带签名,则可跳过此 步骤。
如果您的OBS桶为私有桶,且不希望使用携带签名的URL访问桶内资源,则建议配置以 下桶策略:仅允许Nginx代理服务器的IP地址访问OBS桶。
最佳实践 15 通过 Nginx 反向代理访问 OBS
1. 在OBS管理控制台左侧导航栏选择“对象存储”。 条件 – 条件运算符:IpAddress
– 键:SourceIp – 值:
▪
如果ECS使用公网DNS,取值为:ECS的弹性公网IP地址
▪
如果ECS使用华为云内网DNS,取值为:100.64.0.0/10,214.0.0.0/7,ECS的私有IP地 址
例如访问http://ECS弹性公网IP地址/ocean.jpg
图15-3 使用固定 IP 地址访问 OBS 资源
----结束
最佳实践 15 通过 Nginx 反向代理访问 OBS