【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 @   Mr·Xu  阅读(786)  评论(0编辑  收藏  举报
编辑推荐:
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
阅读排行:
· 百万级群聊的设计实践
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
历史上的今天:
2019-02-18 React Native常用组件之TabBarIOS、TabBarIOS.Item组件、Navigator组件、NavigatorIOS组件、React Navigation第三方
点击右上角即可分享
微信分享提示