1. APP发送Post请求,只需准备空间名和视频文件名
#pragma mark - 使用同步请求,让php来计算
+ (NSString *)syncPostRequestWithUrlString:(NSString *)urlString videoUrlPrefixPartOne:(NSString *)videoUrlPrefixPartOne
{
//第一步,创建URL
NSURL *url = [NSURL URLWithString:kQiNiuSpace];
//第二步,创建请求
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30];
[request setHTTPMethod:@"POST"];//设置请求方式为POST,默认为GET
// 4) 建立请求"数据体",因为要把这个数据体传送给服务器。
NSString *videoName = [urlString stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"http://%@.bkt.clouddn.com/",videoUrlPrefixPartOne] withString:@""];
// 保存下来,后面的方法要用到
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
[userDefault setObject:videoName forKey:@"QiNiuPrivateUrlTool_vidoeName"];
[userDefault synchronize];
NSString *bodyString = [NSString stringWithFormat:@"spacepartone=%@&videoname=%@", videoUrlPrefixPartOne, videoName];
NSLog(@"数据体字符串:%@", bodyString);
// 将生成的字符串,用指定的编码转换成数据Data
NSData *body = [bodyString dataUsingEncoding:NSUTF8StringEncoding];
// NSLog(@"sg_postBody__%@", body);
// 5) 设置可变请求的HTTPBody
[request setHTTPBody:body];
//第三步,连接服务器
NSData *received = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *str1 = [[NSString alloc]initWithData:received encoding:NSUTF8StringEncoding];
NSLog(@"sg__responseString:%@",str1);
// [SGTools showMessage:[NSString stringWithFormat:@"下载中,请勿退出!",str1] duration:5];
return str1;
}
2.利用qiniu1space20161222.php生成加密后的下载URL签名: Token
<?php
final class QiNiu
{
private $accessKey;
private $secretKey;
private $deadLine;
private $finalToken;
// 下载的空间地址的前缀
private $spaceName;
// 下载的文件名 english_02.mp4
private $fileName;
public function __construct($accessKey, $secretKey,$spaceName,$fileName)
{
$this->accessKey = $accessKey;
$this->secretKey = $secretKey;
$this->spaceName = $spaceName;
$this->fileName = $fileName;
}
public function getAccessKey()
{
return $this->accessKey;
}
public function getSecretKey()
{
return $this->secretKey;
}
public function getDeadLine()
{
return $this->deadLine;
}
public function getFinalToken()
{
return $this->finalToken;
}
public function getSpaceName()
{
return $this->spaceName;
}
public function getFileName()
{
return $this->fileName;
}
/**
* 对提供的数据进行urlsafe的base64编码。
*
* @param string $data 待编码的数据,一般为字符串
*
* @return string 编码后的字符串
* @link http://developer.qiniu.com/docs/v6/api/overview/appendix.html#urlsafe-base64
*/
public function base64_urlSafeEncode($data)
{
$find = array('+', '/');
$replace = array('-', '_');
return str_replace($find, $replace, base64_encode($data));
}
public function sign($data)
{
$hmac = hash_hmac('sha1', $data, $this->secretKey, true);
$this->finalToken = $this->base64_urlSafeEncode($hmac);
return $this->accessKey . ':' . $this->finalToken;
}
public function privateDownloadUrl($baseUrl, $expires = 20)
{
$this->deadLine = time() + $expires;
$pos = strpos($baseUrl, '?');
if ($pos !== false) {
$baseUrl .= '&e=';
} else {
$baseUrl .= '?e=';
}
$baseUrl .= $this->deadLine;
$token = $this->sign($baseUrl);
return "$baseUrl&token=$token";
}
}
// $_POST["spacepartone"] --- oegnccmnu
// $_POST["videoname"] --- fighting.mp4
// http://oegnccmnu.bkt.clouddn.com/fighting.mp4?e=1475503451&token=4lI8KkvqhkxU1zpNIVFOn3YhsHza4jcE3_Aqa298:QQIWGBflFBGHJY_MGo5uydS9k7M=
// 对链接进行签名
$accessKey = 'accessKey';
$secretKey = 'secretKey';
// 构建Auth对象
$auth = new QiNiu($accessKey, $secretKey,$_POST["spacepartone"],$_POST["videoname"]);
// 私有空间中的外链 http://<domain>/<file_key>
// 对链接进行签名
$signedUrl = $auth->privateDownloadUrl('http://'.$auth->getSpaceName().'.bkt.clouddn.com/'.$auth->getFileName());
// http://oegnccmnu.bkt.clouddn.com/fighting.mp4?e=1475503451&token=4lI8KkvqhkxU1zpNIVFOn3YhsHza4jcE3_Aqa298:QQIWGBflFBGHJY_MGo5uydS9k7M=
// 下面是自由发挥
$tmpTimeStamp = $auth->getDeadLine();
$encodeTimeStamp = base64_encode($tmpTimeStamp);
// finalToken
$tmpFinalToken = $auth->getFinalToken();
$encodeFinalToken = base64_encode($tmpFinalToken);
// 使用日期等进行连接
// $currentDate = date("Y-m-d").'vwhm.net'.'beyondlovekeke'.'308829827'.$auth->getSpaceName().$auth->getFileName();
$currentDate = date("Y-m-d").'vwhm.net'.'beyondlovekeke'.'308829827'.$auth->getSpaceName().$auth->getFileName();
$encodeCurrentDate = base64_encode($currentDate);
// 取前5个字符串
$firstFiveEncodeCurrentDateString = substr($encodeCurrentDate, 0,5);
$md5date = md5($currentDate);
$encodemd5date = base64_encode($md5date);
// 取前10个字符串
$firstTenEncodeMd5DateString = substr($encodemd5date, 0,10);
// base64编码
// echo 'http://'.$_POST["spacepartone"].'.bkt.clouddn.com/'.$_POST["videoname"].'?e='.$tmpTimeStamp.'&token='.$accessKey.':'.$tmpFinalToken;
// 连接好的字符串 base64_encode
// 14755531732016-10-04acUzYWGo_Q_ruur98Wm2TjhL3Hs=
// $rawJoinString = $tmpTimeStamp.$currentDate.$tmpFinalToken;
// $encodeString = base64_encode($rawJoinString);
// 新的,base编码后的时间戳+base编码后的日期+base编码后的token
$rawJoinString = $firstTenEncodeMd5DateString.$encodeTimeStamp.'|'.$firstFiveEncodeCurrentDateString.$encodeFinalToken;
// 最后再来一次base编码
$encodeString = base64_encode($rawJoinString);
// 加个服务器的时间戳,目的是:避免用户自己改手机的时间
echo time()."^_^".$encodeString;
3. 在app中, 对php文件 echo 回来的 Token 进行反向解密, 从而拼出下载url
+ (NSString *)encodeUrlString:(NSString *)downloadUrlString videoUrlPrefixPartOne:(NSString *)videoUrlPrefixPartOne
{
NSString *resposnseString = [self syncPostRequestWithUrlString:downloadUrlString videoUrlPrefixPartOne:videoUrlPrefixPartOne];
// 先使用^_^分割,获取前一段的时间戳,如果服务器时间与本机的时间,相差25个小时,则说明,用户自己乱设置了时间!
NSArray *tmpArr = [resposnseString componentsSeparatedByString:@"^_^"];
long long serverTimeStamp = [[tmpArr firstObject] longLongValue];
// 1479040800
NSString *rawResponseStr = [tmpArr lastObject];
NSTimeInterval clientTimeStamp = [[NSDate date] timeIntervalSince1970];
NSLog(@"sg__client:%f",clientTimeStamp);
NSLog(@"sg__client:%f",fabs(clientTimeStamp));
double gap = fabs(fabs(clientTimeStamp) - serverTimeStamp);
NSLog(@"sg__gap:%f",fabs(fabs(clientTimeStamp) - serverTimeStamp));
// 时间戳合法,即在+ -24个小时以内
if (gap < 24 * 3600) {
return [self decodeResponseString:rawResponseStr videoUrlPrefixPartOne:videoUrlPrefixPartOne];
}
// 提示:客户端时间非法
[SGTools showMessage:@"客户端时间不正确" duration:10];
return @"";
}
// 反向解密 php加密返回的字符串
+ (NSString *)decodeResponseString:(NSString *)responseString videoUrlPrefixPartOne:(NSString *)videoUrlPrefixPartOne
{
NSString *rawJoinString = [responseString base64DecodedString];
// NSLog(@"sg_rawJoinString__%@",rawJoinString);
// $encodeTimeStamp.$firstFiveEncodeCurrentDateString.$encodeFinalToken;
// 先算出
NSArray *tmpArr = [rawJoinString componentsSeparatedByString:@"|"];
// NSString *encodeMd5Date = [self encodeMd5Date];
// NSString *timeStamp = [encodeTimeStamp stringByReplacingOccurrencesOfString:encodeMd5Date withString:@""];
// NSString *md5AndTimeStamp = [timeStamp base64DecodedString];
NSString *encodeTimeStamp = [tmpArr[0] substringFromIndex:10];
NSString *timeStamp = [encodeTimeStamp base64DecodedString];
timeStamp = [NSString stringWithFormat:@"%lld",[timeStamp longLongValue]];
// NSLog(@"sg_timeStamp__%@",timeStamp);
NSString *encodeFinalToken = [tmpArr[1] substringFromIndex:5];
NSString *finalToken = [encodeFinalToken base64DecodedString];
// NSLog(@"sg_finalToken__%@",finalToken);
// 根据用户上次选择的,展示
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
NSString *videoName = [userDefault objectForKey:@"QiNiuPrivateUrlTool_vidoeName"];
[userDefault synchronize];
// http://oegnccmnu.bkt.clouddn.com/fighting.mp4?e=1475503451&token=4lI8KkvqhkxU1zpNIVFOn3YhsHza4jcE3_Aqa298:QQIWGBflFBGHJY_MGo5uydS9k7M=
NSString *plainDownloadUrlString = [NSString stringWithFormat:@"%@%@?e=%@&token=%@:%@",[NSString stringWithFormat:@"http://%@.bkt.clouddn.com/",videoUrlPrefixPartOne],videoName,timeStamp,kQiNiuAccessKey,finalToken];
// NSLog(@"sg_plainDownloadUrlString__%@",plainDownloadUrlString);
return plainDownloadUrlString;
}