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

NSURLSession sending token back to server for getting data

我有应用 iPhone 应用,它将使用 API 的调用。 我用 Username/Password 和 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];

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

http响应码:500 http响应头:{ "Cache-Control" = "no-cache"; "Content-Length" = 36; "Content-Type" = "application/json; charset=utf-8";日期 = "Thu, 06 Oct 2016 12:16:58 GMT";过期 = "-1";编译指示 = "no-cache";服务器 = "Microsoft-IIS/8.5"; "X-AspNet-Version" = "4.0.30319"; "X-Powered-By" = "ASP.NET"; }

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

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

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

请帮帮我.....我从昨天就被困在这里了...

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

尝试像这样在第二次调用中设置 header 字段:

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

基本上,auth header 字段应该如下所示(来自邮递员): image

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

如前所述,我很确定它应该是:

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

也就是说,500 错误是内部服务器错误,而不是身份验证错误。看起来真正的问题可能与身份验证无关,并且您的请求本身在某种程度上存在格式错误,或者服务器端代码中存在您不知何故发痒的错误。

此外,您的代码似乎没有检查响应中是否确实存在令牌,除非您在其他地方这样做。

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