我正在使用OneDrive
协议将大文件上传到BITS
。这是documentation
我遇到以下问题。在我尝试创建会话后登录一段时间后,我收到401错误。这是完整的回复:
<NSHTTPURLResponse: 0x7d6ee0f0> { URL: https://cid-da1cedf5484811a9.users.storage.live.com/items/DA1CEDF5484811A9!373/IMG_0003.JPG } { status code: 401, headers {
"BITS-Packet-Type" = Ack;
"Content-Length" = 0;
Date = "Mon, 22 Dec 2014 09:50:22 GMT";
P3P = "CP=\"BUS CUR CONo FIN IVDo ONL OUR PHY SAMo TELo\"";
Server = "Microsoft-HTTPAPI/2.0";
"X-AsmVersion" = "UNKNOWN; 19.9.0.0";
"X-ClientErrorCode" = AccessDenied;
"X-MSNSERVER" = "SN3301____PAP101";
"X-QosStats" = "{\"ApiId\":0,\"ResultType\":2,\"SourcePropertyId\":0,\"TargetPropertyId\":42}";
"X-ThrowSite" = "4e1b.c093";
} }
以下是我的要求:
{
Authorization = "EwCAAq1DBAAUGCCXc8wU/zFu9QnLdZXy+YnElFkAAYejThC8LqFmGJx4sT4Wv11wzA6Cj9tleMQ+PM4PGXSV/DAorkfRiVnt+KQnZRI90XL/FIfwTvhWmp6jFhsppM39GgwbQ7it0tSVCSp4cIFCFSphmV783o+MKPeuEsw79mRGL5Kz2lcrVUxQAq12vUZXnhkX4qiJj0RqMSdaFYghfVVmhkcGsJITOwIisFq/JyaRoffgcW7vZCu9/9Q1Jm62f+bcGur82sTo5ucwV4M7QNtl77nVjv3tPElcUDgZnTvCLuhIE6QHY6yHS+9blWVbaXJBBD0ZPjDbUdjIlbexto6VvXtjp+vELL8rMSJMYcGjN4AxbGmBDnjLm9Iy1RIDZgAACALsAIEvRqDnUAFmIs8toBlRzfxctJcm1wxfqY/531QSDMVG9pIISpNCPppHAa/blSV8+LbLO/hW5i/36/3RTLpFAiXkPxzbkI8OJSrVRDfKcXiK1x+kTNFtcxXLBlJSWYlMY9OcwT+v/JTQnoGD1z6L56zOX53Gt7SBZQ0of7e3QecxHLX7w9lqs0jBmRvwL9I/n0+r9r6CI3tTEnFODFyED9ToBCRwwjLLD8P4qWRXWC1BUL+20v2QCQYRKzSDxZkYa3WrPLA4PIEFdFp58/limBzDrGW4MaWi1UgaI/QF8gN5n+JLNE4YcZL8KaXFZ76zNWNhJFsg4Lctsu95l7oD9MkezDvpA8bhkoNp39rEvPjBEurrFkdHviv73Z/C1W+IoA4ww3ZAYtIt3THtvPE4wq2fUEcb+MhOIG7abZtu4P07+5Zy2UO1rGlChE/pvmtV4XXrrg3TLG5zAQ==";
"BITS-Packet-Type" = "Create-Session";
"BITS-Supported-Protocols" = "{7df0354d-249b-430f-820d-3d2a9bef4931}";
"X-Http-Method-Override" = "BITS_POST";
}
如果需要,我可以发布用于打开会话的代码,我现在不发布它,因为它非常大。
好的,我想到的第一件事就是访问令牌已经过时了,我需要以某种方式更新它。但!就在我使用相同的访问令牌执行检索用户ID的请求之前:
- (void)retrieveUserId
{
NSString *urlString = [NSString stringWithFormat:@"https://apis.live.net/v5.0/me?access_token=%@", commonAccessToken];
NSURL *url = [NSURL URLWithString:urlString];
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration];
NSURLSessionDataTask *task = [session dataTaskWithURL:url
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if (httpResponse.statusCode == 200)
{
NSLog(@"Response retrieving user id %@", httpResponse);
NSError *parsingError = nil;
NSDictionary *parsedDictionary = [NSJSONSerialization JSONObjectWithData:data
options:kNilOptions
error:&parsingError];
if (!parsingError)
{
commonUserId = parsedDictionary[@"id"];
[self createUploadRequest];
}
else
{
dispatch_async(dispatch_get_main_queue(), ^{
[self.delegate bitsClient:self didFailWithError:parsingError];
});
}
}
else
{
dispatch_async(dispatch_get_main_queue(), ^{
[self.delegate bitsClient:self didFailWithError:error];
});
}
}];
[task resume];
}
它有效。当我获得用户ID时,此访问令牌是可以的。但是你可以看到,与尝试打开会话时不同,访问令牌是作为url的一部分放置的,而不是作为头字段之一。我不确定它是否重要。到现在为止我无法解释这种行为。如果我退出并再次登录,那么它再次正常,我不再收到401错误,所以可能我真的应该更新令牌,但怎么办呢?还有一件事让你知道 - 当我从LiveConnectSession
获得访问令牌时,我会检查这个会话是否过期而不是。其expires
属性晚于[NSDate date]
。
还有一件事让你知道 - 尽管我无法打开会话,如果我尝试使用Live SDK
的{{1}}上传文件,我的请求会被401错误拒绝文件上传没有任何错误。
我想恢复:经过一段时间(似乎是24小时但我不确定)以LiveOperation
用户身份登录后,我无法使用OneDrive
协议上传文件因为我收到401错误。同时会话似乎没有过期,我仍然可以使用BITS
上传文件。此外,我可以使用打开上传会话时使用的相同访问令牌轻松获取用户ID。如果我退出并再次登录,那么一切都像魅力一样,我能够创建会话和上传文件。
似乎这就是我可以告诉你的全部内容,但如果您需要任何其他信息,请告诉我。非常感谢任何帮助。
答案 0 :(得分:0)
您在问题中提供的回复肯定表明问题与身份验证有关 - 特别是OneDrive无法识别提供的身份验证。到期是最可能的解释,因此令人耳目一新的答案可能就是答案。如果您请求“wl.offline_access”范围以及您需要的其他范围,则应该将“refresh_token”作为OAuth 2.0流程的一部分返回,因此当前一个过期时,允许创建新的“access_tokens” 。我相信Live SDK本身可以处理刷新过程,但我并不完全熟悉这方面的事情 - 现在确保请求范围,如果SDK处理其余部分,我们将一起学习:)
答案 1 :(得分:0)
安德烈,我是php开发人员,这就是我在php中所做的事情:
const API_URL = 'https://apis.live.net/v5.0/';
const INITAPIURL = 'https://login.live.com/oauth20_token.srf';
const URI_AUTHORIZE = 'https://login.live.com/oauth20_authorize.srf';
1)获取访问令牌并保存刷新令牌(下面的函数生成URL以重定向用户oAuth)
public function getAuthorizeUrl($cburl) {
$cburl=_SKYDRIVE_REDIRECT_URI;
return self::URI_AUTHORIZE.'?client_id='.urlencode(_SKYDRIVE_API_CLIENT_ID).'&scope='.urlencode('wl.offline_access wl.skydrive wl.skydrive_update wl.emails wl.contacts_skydrive wl.contacts_photos').'&response_type=code&redirect_uri='.urlencode($cburl);
}
2)每隔3300秒(访问令牌直播3600秒)我直接在服务器上刷新访问令牌和刷新令牌(在浏览器中没有用户确认)
$r = $this->http(self::INITAPIURL, 'POST', array("grant_type" => "refresh_token", "client_id" => _SKYDRIVE_API_CLIENT_ID, "client_secret" => _SKYDRIVE_API_SECRET, "redirect_uri" => _SKYDRIVE_REDIRECT_URI, "refresh_token" => $this->refreshtoken));
3)我发送访问令牌作为带有curl的标头,用于我对API的所有请求(上面的令牌刷新除外)
$headers[] = "Authorization: Bearer " . $this->token;
以上步骤在我使用BITS时工作(我刚刚在perl上实现了BITS协议,一切正常)
P.S。谢谢你发了ID文件夹的URL,他们在文档中有错误的URL:)