随笔:接入腾讯云图片存储实战

一、需求

客户端为了合规访问的图片必须经过加密才能访问,项目组决定对接腾讯云cos服务。

腾讯云COS服务是将图片保存到腾讯云服务器中,客户端将图片上传上去,返回一个客户端自定义的图片地址,客户端将图片传给cos服务器,cos服务器将临时访问的图片链接给到客户端,客户端展示给用户看。如果中间人hook到自定义图片地址是无法得到该图片的,这样就可以确保项目服务器个人信息安全。

二、接入实操

001 图片都是存入专有的bucket中,可以理解为一个专有子目录。

002 注册COS服务 这里注册一次就行 注册参数例如 appID regionName 设置请求代理等

003 通过服务器接口的到访问专有bucket的一些参数例如secretID secretKey token experationDate等 将这些参数请求腾讯云授权服务

004 得到访问授权后 将我们的图片传入服务器 这里需要配置一些参数:桶的名称 ,自定义图片key ,上传图片路径等

这里我建立一个工具类文件便于使用

//
//  QCloudTools.h
//  
//
//  Created by maochengfang on 2021/3/16.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface QCloudTools : NSObject

SingletonH();

@property (nonatomic, assign) long long expiredTime;
@property (nonatomic, copy) NSString* filePath;
@property (nonatomic, copy) NSString* region;
@property (nonatomic, copy) NSString* sessionToken;
@property (nonatomic, copy) NSString* tmpSecretId;
@property (nonatomic, copy) NSString* tmpSecretKey;
@property (nonatomic, copy) void(^uploadImageCloudPath)(NSString* path);

@property (nonatomic, strong) void (^presinedImageCloudPath)(NSDictionary *imageDict);


- (void)registerCOSXMLService;
- (void)setUp;
/**
 * 高级接口上传对象
 */
- (void)transferUploadFile:(NSString *)filePath;

/*
 获取下载预览图片
 */
- (void)PutObjectWithPresignedURL:(NSString *)fileURL;
@end

NS_ASSUME_NONNULL_END
//
//  QCloudTools.m
//  
//
//  Created by maochengfang on 2021/3/16.
//

#import "QCloudTools.h"

@interface QCloudTools ()<QCloudSignatureProvider, QCloudCredentailFenceQueueDelegate>
@property (nonatomic) QCloudCredentailFenceQueue* credentialFenceQueue;
@end

@implementation QCloudTools

SingletonM();

- (void)setUp {
    // 注册默认的 COS 服务
    QCloudServiceConfiguration* configuration = [QCloudServiceConfiguration new];
    //关闭读取系统剪贴板的功能
    configuration.appID = @"";
    configuration.signatureProvider = self;
    QCloudCOSXMLEndPoint* endpoint = [[QCloudCOSXMLEndPoint alloc] init];
    endpoint.regionName = kRegion;
    endpoint.useHTTPS = YES;
    configuration.endpoint = endpoint;
   
    [QCloudCOSXMLService registerDefaultCOSXMLWithConfiguration:configuration];
    [QCloudCOSTransferMangerService registerDefaultCOSTransferMangerWithConfiguration:configuration];
    
    self.credentialFenceQueue = [QCloudCredentailFenceQueue new];
    self.credentialFenceQueue.delegate = self;
    [QCloudCOSXMLConfiguration sharedInstance].currentRegion = kRegion;
    QCloudServiceConfiguration* configuration1 = [[QCloudCOSXMLService defaultCOSXML].configuration copy];
    configuration1.endpoint.regionName = kRegion;
    [QCloudCOSTransferMangerService registerCOSTransferMangerWithConfiguration:configuration1 withKey:kRegion];
    
    [QCloudCOSXMLService registerCOSXMLWithConfiguration:configuration1 withKey:kRegion];
  
    self.isRegister = YES;
   
}

- (void)registerCOSXMLService{
  
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        
        [self fetchData];
    });
}

- (void) fenceQueue:(QCloudCredentailFenceQueue * )queue requestCreatorWithContinue:(QCloudCredentailFenceQueueContinue)continueBlock
{
    QCloudCredential* credential = [QCloudCredential new];
    //在这里可以同步过程从服务器获取临时签名需要的 secretID,secretKey,expiretionDate 和 token 参数
    credential.secretID = self.tmpSecretId;
    credential.secretKey = self.tmpSecretKey;
    credential.token = self.sessionToken;
    
    /*强烈建议返回服务器时间作为签名的开始时间,用来避免由于用户手机本地时间偏差过大导致的签名不正确 */
//    credential.startDate = [NSDate dateWithTimeIntervalSince1970:[SADateFormatTool getCurrentTimestamp]]; // 单位是秒
    credential.experationDate = [NSDate dateWithTimeIntervalSince1970:self.expiredTime];;
    QCloudAuthentationV5Creator* creator = [[QCloudAuthentationV5Creator alloc]
        initWithCredential:credential];
    continueBlock(creator, nil);
}

- (void) signatureWithFields:(QCloudSignatureFields*)fileds
                     request:(QCloudBizHTTPRequest*)request
                  urlRequest:(NSMutableURLRequest*)urlRequst
                   compelete:(QCloudHTTPAuthentationContinueBlock)continueBlock
{
    //在这里可以同步过程从服务器获取临时签名需要的 secretID,secretKey,expiretionDate 和 token 参数
    
    QCloudCredential* credential = [QCloudCredential new];
    credential.secretID = self.tmpSecretId;
    credential.secretKey = self.tmpSecretKey;
    credential.token = self.sessionToken;
    credential.experationDate = [NSDate dateWithTimeIntervalSince1970:self.expiredTime];;
    QCloudAuthentationV5Creator* creator = [[QCloudAuthentationV5Creator alloc] initWithCredential:credential];
    QCloudSignature* signature =  [creator signatureForData:urlRequst];
    NSLog(@"_signature===%@&x-cos-security-token=%@",signature.signature,self.sessionToken);
    continueBlock(signature, nil);
}


- (void)fetchData {
    
//  根据用户信息: 获取当前用户所有地区下的存储桶列表,
//    实例化 QCloudGetServiceRequest
//    调用 QCloudCOSXMLService 实例的 GetService 方法 发起请求
//    在FinishBlock获取结果
    QCloudGetServiceRequest* request = [QCloudGetServiceRequest new];
    DEF_WeakSelf(self)
    [request setFinishBlock:^(QCloudListAllMyBucketsResult * _Nullable result, NSError * _Nullable error) {
        
        NSLog(@"result=====%@",result);
        
    }];
    
    [[QCloudCOSXMLConfiguration sharedInstance].currentService GetService:request];
}


/**
 * 高级接口上传对象
 */
- (void)transferUploadFile:(NSString *)filePath{
    
    //.cssg-snippet-body-start:[objc-transfer-upload-file]
    QCloudCOSXMLUploadObjectRequest* put = [QCloudCOSXMLUploadObjectRequest new];
    // 本地文件路径
    NSURL* url = [NSURL fileURLWithPath:filePath];
    put.accessControlList = @"default";
    // 存储桶名称,格式为 BucketName-APPID
    put.bucket = @"";
    
    // 对象键,是对象在 COS 上的完整路径,如果带目录的话,格式为 "dir1/object1"
    put.object = [NSString stringWithFormat:@"/%@ios-%ld.png",self.filePath,[SADateFormatTool getCurrentTimestamp]];
    
    // 需要上传的对象内容。可以传入NSData*或者NSURL*类型的变量
    put.body =  url;
    WS(weakSelf);
    
    // 监听上传结果
    [put setFinishBlock:^(QCloudUploadObjectResult* outputObject, NSError *error) {
        // 可以从 outputObject 中获取 response 中 etag 或者自定义头部等信息
        NSDictionary * result = (NSDictionary *)outputObject;
        [SVProgressHUD dismissWithDelay:1];
        if (!error) {
            
            NSLog(@"下载链接:%@\n\n",outputObject.location);

        }
    }];
    
    [put setSendProcessBlock:^(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) {
        dispatch_async(dispatch_get_main_queue(), ^{
//            bytesSent  本次发送的字节数
//            totalBytesSent  总共发送的字节数
//            totalBytesExpectedToSend  总共需要发送的字节数(即整个文件的大小)
            
//            [weakself.progressView setProgress:(1.0f*totalBytesSent)/totalBytesExpectedToSend animated:YES];
            NSString* str = [NSString stringWithFormat:@"上传中(%.0f%%)",1.0f*totalBytesSent/totalBytesExpectedToSend * 100];
            
            [SVProgressHUD showWithStatus:str];
            NSLog(@"progressView ====%@",str);
        });
    }];
    
    [[QCloudCOSTransferMangerService defaultCOSTransferManager] UploadObject:put];
    
    //.cssg-snippet-body-end
}

- (void)PutObjectWithPresignedURL:(NSString *)fileURL{
    
    NSString* objct =  [fileURL stringByReplacingOccurrencesOfString:@"https://qiangdan-1255789551.cos.ap-shanghai.myqcloud.com" withString:@""];
    NSLog(@"currentThread---%@",[NSThread currentThread]);
    
    QCloudGetPresignedURLRequest* getPresignedURLRequest = [[QCloudGetPresignedURLRequest alloc] init];
    getPresignedURLRequest.bucket = [NSString stringWithFormat:@"%@-1255789551",@"qiangdan"];;
    getPresignedURLRequest.HTTPMethod = @"GET";
    getPresignedURLRequest.object = objct;
    WS(weakSelf);
   
    [getPresignedURLRequest setFinishBlock:^(QCloudGetPresignedURLResult * _Nullable result, NSError * _Nullable error) {
            
       
        // 预签名 URL
            NSString* presignedURL = result.presienedURL;

    }];
    
    [[QCloudCOSXMLService defaultCOSXML] getPresignedURL:getPresignedURLRequest];
}


@end

三、总结

仔细文档多和同事一起讨论

官方文档

官方文档1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值