NSURLSession将令牌发送回服务器以获取数据

时间:2016-10-07 06:15:55

标签: ios objective-c iphone nsurlconnection nsurlsession

我有应用程序iPhone应用程序将使用API​​的调用。 我使用NSURLSession用户名/密码成功拨打电话,并从服务器接收令牌....

NSString *username = @"admin";
NSString *password = @"test";
NSString *authString = [NSString stringWithFormat:@"%@:%@",
                        username,
                        password];

// 2 - convert authString to an NSData instance
NSData *authData = [authString dataUsingEncoding:NSUTF8StringEncoding];

// 3 - build the header string with base64 encoded data
NSString *authHeader = [NSString stringWithFormat: @"Basic %@",
                        [authData base64EncodedStringWithOptions:0]];

// 4 - create an NSURLSessionConfiguration instance
NSURLSessionConfiguration *sessionConfig =
[NSURLSessionConfiguration defaultSessionConfiguration];

// 5 - add custom headers, including the Authorization header
[sessionConfig setHTTPAdditionalHeaders:@{
                                          @"Accept": @"application/json",
                                          @"Authorization": authHeader
                                          }
 ];

// 6 - create an NSURLSession instance
NSURLSession *session =
[NSURLSession sessionWithConfiguration:sessionConfig delegate:self
                        delegateQueue:nil];

// 7 - create an NSURLSessionDataTask instance
NSString *urlString = @"http://test.myserver.am/api/authentication/Login?username=admin&password=test";
NSURL *url = [NSURL URLWithString:urlString];
NSURLSessionDataTask *task = [session dataTaskWithURL:url
                                    completionHandler:
                              ^(NSData *_Nullable data, NSURLResponse *_Nullable response, NSError *_Nullable error) {
                                  if (error)
                                  {
                                      // do something with the error

                                      return;
                                  }

                                  NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
                                  if (httpResponse.statusCode == 200)
                                  {
                                      arrTokenData = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];

                                      [self getDomain];
                                  } else {
                                      // failure: do something else on failure
                                      NSLog(@"httpResponse code: %@", [NSString stringWithFormat:@"%ld", (unsigned long)httpResponse.statusCode]);
                                      NSLog(@"httpResponse head: %@", httpResponse.allHeaderFields);

                                      return;
                                  }
                              }];

// 8 - resume the task
[task resume];

现在我正在使用从服务器收到的令牌并进行另一次调用以获取用户数据......

[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];

        NSString *authValue = [arrTokenData valueForKey:@"Token"];

        //Configure session with common header fields
        NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
        sessionConfiguration.HTTPAdditionalHeaders = @{@"bearer": authValue};

        NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration];

        NSString *url = @"http://test.myserver.am/api/mobile/LookUps/getuserdata";
        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];

        NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
            [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
            if (!error) {
                NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
                if (httpResponse.statusCode == 200)
                {
                    NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers|NSJSONReadingAllowFragments error:nil];

                    //Process the data
                }
            }

        }];
        [task resume];

但是我收到以下状态代码并且....请求未获得成功....

httpResponse代码:500 httpResponse head:{“Cache-Control”=“no-cache”; “内容长度”= 36; “Content-Type”=“application / json; charset = utf-8”;日期=“星期四,2016年10月6日12:16:58 GMT”; Expires =“ - 1”; Pragma =“no-cache”; Server =“Microsoft-IIS / 8.5”; “X-AspNet-Version”=“4.0.30319”; “X-Powered-By”=“ASP.NET”; }

****请注意,相同的API在另一个(xamarin APP)平台上运行良好.... **

我正在使用Objective-C .... IOS10

我的发送令牌请求是否正确....?

请帮帮我.....我昨天被困在这里......

2 个答案:

答案 0 :(得分:1)

正如已经提到的,我非常确定它应该是:

    NSString *authValue = [NSString stringWithFormat:@"Bearer %@",
        [arrTokenData valueForKey:@"Token"]];
    sessionConfiguration.HTTPAdditionalHeaders = @{@"Authorization": authValue};

据说,500错误是内部服务器错误,而不是身份验证错误。似乎真正的问题与身份验证无关,并且您的请求本身在某种程度上是格式错误的,或者服务器端代码中存在您以某种方式发痒的错误。

此外,您的代码似乎没有检查令牌是否确实存在于回复中,除非您在其他地方执行此操作。

我首先检查以确保令牌实际存在,如果是,启用您可以在服务器上启用的任何调试,并查看日志以尝试找出导致服务器上500错误的原因侧。有可能,一旦你看到服务器端实际发生了什么,修复就会很明显。

答案 1 :(得分:0)

首先,您不应在第一次身份验证调用中在ULR中传递用户名/密码,因为您已将其作为标头字段传递。 URL中的参数不安全。应始终使用POST而不是GET方法传递敏感数据。但这不是问题所在。

尝试在第二个调用中设置标题字段,如下所示:

NSString *authorizationHeader = [NSString stringWithFormat: @"Bearer %@", authValue];
[sessionConfig setHTTPAdditionalHeaders:@{
                                      @"Accept": @"application/json",
                                      @"Authorization": authorizationHeader
                                      }
];

基本上,auth头字段应该是这样的(来自邮递员): image

注意:我没有测试/构建我的代码!