将file upload到OneDrive。 401错误

我正在实施使用BITS协议上传大文件到OneDrive 。 这里是文档

我有以下问题。 经过一段时间的login时,我想创build一个会话,我收到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]; } 

它工作。 获取用户标识时,此访问令牌正常。 但是你可以在这里看到,与试图打开一个会话时不同,访问令牌是作为URL的一部分,而不是作为头部字段之一。 我不确定是否重要。 现在我无法解释这种行为。 如果我注销并再次login,那么再次确定,我不再收到401错误,所以可能我应该更新令牌,但是怎么做呢? 还有一件事要让你知道 – 当我从LiveConnectSession获取访问令牌时,我检查这个会话是否过期,而不是。 其expires属性晚于[NSDate date]

还有一件事要知道 – 尽pipe我无法打开会议和我的要求被拒绝401错误,如果我尝试使用Live SDKLiveOperation上传文件的file upload没有任何错误。

我想继续:经过一段时间(似乎是24小时,但我不确定)以OneDrive用户身份login后,我变得无法使用BITS协议上传文件,因为我收到401错误。 同时会话似乎没有过期,我仍然可以通过使用LiveOperation上传文件。 另外,我可以使用打开上传会话时使用的相同访问令牌轻松获取用户ID。 如果我注销并再次login,然后再次一切工作就像魅力,我可以创build会话和上传文件。

似乎这是我能告诉你的一切,但如果你需要任何额外的信息,请告诉我。 任何帮助,非常感激。

您在问题中提供的答复明确指出,问题是身份validation – 特别是OneDrive不能识别提供的身份validation。 到期是最可能的解释,所以提醒可能是答案。 如果您要求“wl.offline_access”作用域以及您需要的其他作用域,则应将“refresh_token”作为OAuth 2.0stream程的一部分返回,因此,如果前一个作废,则允许创build新的“access_tokens” 。 我相信Live SDK本身可以处理刷新过程,但是我并不完全熟悉这方面的东西 – 现在请确保请求范围,如果SDK处理其他问题,我们将一起学习。

安德烈,我是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来redirectoAuth用户)

 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协议,一切正常)

PS谢谢你张贴的文件夹的URL由他们在文档中有错误的URL的ID