【iOS】上传图片到七牛过程(生成Token,上传)

  1、生成Token(可移动端写,也可由服务器返回),我们的Token有两种,自己写了一个,然后服务器也有一个,为了考虑安全性,取消了个人写的。

  移动端生成Token

#import <Foundation/Foundation.h>

@interface QNToken : NSObject

/**
 *  生成七牛UploadToken, 需要自己设置token有效时间
 *
 *  @param scope     Scope
 *  @param accessKey AccessKey
 *  @param secretKey SecretKey
 *  @param deadline  token有效时间, UNIX时间戳
 *
 *  @return 生成的UploadToken
 */
+ (NSString *)createTokenWithScope:(NSString *)scope accessKey:(NSString *)accessKey secretKey:(NSString *)secretKey liveTime:(NSInteger)deadline;

/**
 *  生成七牛UploadToken, token有效时间默认1小时
 *
 *  @param scope     Scope
 *  @param accessKey AccessKey
 *  @param secretKey SecretKey
 *
 *  @return 生成的UploadToken
 */
+ (NSString *)createTokenWithScope:(NSString *)scope accessKey:(NSString *)accessKey secretKey:(NSString *)secretKey;
@end
#import "QNToken.h"
#import "QN_GTM_Base64.h"
#import <CommonCrypto/CommonHMAC.h>

@implementation QNToken
#pragma mark - 生成token
/** 生成七牛UploadToken, 需要自己设置token有效时间 */
+ (NSString *)createTokenWithScope:(NSString *)scope accessKey:(NSString *)accessKey secretKey:(NSString *)secretKey liveTime:(NSInteger)deadline {
    // 1.确定上传策略
    NSMutableDictionary *jsonDict = [[NSMutableDictionary alloc] init];
    jsonDict[@"scope"] = scope;
    jsonDict[@"deadline"] = @(deadline);
    
    // 2.将上传策略序列化成为json格式:
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonDict
                                                       options:0
                                                         error:nil];
    
    // 3.对json序列化后的上传策略进行URL安全的Base64编码,得到如下encoded:
    NSString* encoded = [self URLSafeBase64Encode:jsonData];
    
    // 4.用SecretKey对编码后的上传策略进行HMAC-SHA1加密,并且做URL安全的Base64编码,得到如下的encoded_signed:
    NSString *encoded_signed = [self HMACSHA1:secretKey text:encoded];
    
    // 5.将 AccessKey、encode_signed 和 encoded 用 “:” 连接起来,得到如下的UploadToken:
    NSString *uploadToken=[NSString stringWithFormat:@"%@:%@:%@",accessKey,encoded_signed,encoded];
    
    return uploadToken;
}

/** 生成七牛UploadToken, token有效时间默认1小时 */
+ (NSString *)createTokenWithScope:(NSString *)scope accessKey:(NSString *)accessKey secretKey:(NSString *)secretKey {
    NSInteger deadline = [[NSDate date] timeIntervalSince1970] + 3600;
    return [self createTokenWithScope:scope accessKey:accessKey secretKey:secretKey liveTime:deadline];
}

#pragma mark - 编码及加密
// URL安全的Base64编码
+ (NSString *)URLSafeBase64Encode:(NSData *)text {
    
    NSString *base64 = [[NSString alloc] initWithData:[QN_GTM_Base64 encodeData:text] encoding:NSUTF8StringEncoding];
    base64 = [base64 stringByReplacingOccurrencesOfString:@"+" withString:@"-"];
    base64 = [base64 stringByReplacingOccurrencesOfString:@"/" withString:@"_"];
    return base64;
}

// HMAC-SHA1加密,并且做URL安全的Base64编码
+  (NSString *)HMACSHA1:(NSString *)key text:(NSString *)text {
    const char *cKey = [key cStringUsingEncoding:NSUTF8StringEncoding];
    const char *cData = [text cStringUsingEncoding:NSUTF8StringEncoding];
    char cHMAC[CC_SHA1_DIGEST_LENGTH];
    CCHmac(kCCHmacAlgSHA1, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
    NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC length:CC_SHA1_DIGEST_LENGTH];
    NSString *hash = [self URLSafeBase64Encode:HMAC];
    return hash;
}


@end

  2、使用

let manager = QNUploadManager.init()
            let option = QNUploadOption.init(mime: nil, progressHandler: { (key, percet) in
                
            }, params: nil, checkCrc: false, cancellationSignal: nil)
            
            let token = QNToken.createToken(withScope: "oops-cos", accessKey: "INgvXHa3e1***************d9cH*****", secretKey: "12r7*****************6TPcXkv*******")
            let imageId = "\(Int64(Date.init().timeIntervalSince1970 * 1000))"
            manager?.put(image.resized(toWidth: 828)?.pngData(), key: imageId, token: token, complete: { (info, key, resp) in
//                chatObj!.setObject(imageWH + "/" + imageName, forKey: "content")
                if let result = resp {
                    if let imagename = result["key"] as? String {
                        chatObj!.setObject(imageWH + "/" + imagename + "/" + self.targetId!, forKey: "content")
                        chatObj!.saveInBackground { (success, error) in
                            if !success {
                               //TODO: 发布出去错误
                            }
                        }
                    }
                }
            }, option: option)

 

posted @ 2020-02-18 22:33  Mr·Xu  阅读(764)  评论(0编辑  收藏  举报