Swift无法发送请求,但Postman成功

时间:2018-08-08 21:23:14

标签: ios swift

编辑2:我最终只是切换到POST请求,并将latitudelongitudedeviceToken放在正文中。这解决了问题。我猜想如果查询字符串太长,iOS将截断标题。我会将其发布为答案,但这更多是替代方法,而不是解决方法。


编辑1:将一些日志添加到服务器后,我发现了问题。由于某种原因,iOS切断了我的身份验证令牌的结尾。这是服务器上记录的内容(长度1015):

Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImNjMTFhZWFlYmNhMjJlNzIzYzRhZDE5ZTQzNTgxNmE5ZGM4MTllMjk4OGUyMzZmYTUzYjMwNDUyYTQ2YzhkZDg2NjVlYTU4ZGJmYmY0MTIwIn0.eyJhdWQiOiIxMCIsImp0aSI6ImNjMTFhZWFlYmNhMjJlNzIzYzRhZDE5ZTQzNTgxNmE5ZGM4MTllMjk4OGUyMzZmYTUzYjMwNDUyYTQ2YzhkZDg2NjVlYTU4ZGJmYmY0MTIwIiwiaWF0IjoxNTMzNzYwNjk1LCJuYmYiOjE1MzM3NjA2OTUsImV4cCI6MTU2NTI5NjY5NSwic3ViIjoiMSIsInNjb3BlcyI6W119.OSu3q5Gxj6Sad5B44J1kUTHs0H9Yc86Hw0oXtm-CmXyO_NirIX3oVxvEsACGpn-4gMMFOx61pJ4mb43pTg9dhIgmgDmywv5mkzRC-pLd5PiSaq4YpxFxlbk_rXZWDXGgGeLwh9iZl7-ByusECeKdn0LrqE3X0XrEehU25OLPI-lDq_hREVMV-eE4zTAunCbhLGMbNCMYZuvEB8NwBhKZSpdoIGS1buZmiUCupUTajgkgfMAVup2ym45s_0eIPvLjcDZgVvpaUgkvUBUPVcEoz-kkL7BTQjmgz0aPLhWYA116pa8pU_lwzuBzU7T85FCy6Mqlas6sg2aGI5RFhcWpFrNHvenNJ7Hd3PlgZHj5bHXpEmQtu93-50Z1tkG4h-wOZ9vxV9WHvDDRzfUg5aivqJtje1dLVLkyb2Eov_gpxhJWHSeAK3laN7_K0YL_gXN0lPey8kMsSuX74rPlOuiKZXsooYoP2VU_4EMxJgBPtUjuBq4o4RqZulFQljLUN02iPaevL1c3Q9LBlXr81O6qhKTjRZ4M3fdxjRkODgBnarQhGdGTnpwSnMn1UtUvjjTJKlnrRxwj4nsZCQI06YHXB06GOV85-5ChB6-c1xFa_Xp

在iOS中(长度为1079):

Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImNjMTFhZWFlYmNhMjJlNzIzYzRhZDE5ZTQzNTgxNmE5ZGM4MTllMjk4OGUyMzZmYTUzYjMwNDUyYTQ2YzhkZDg2NjVlYTU4ZGJmYmY0MTIwIn0.eyJhdWQiOiIxMCIsImp0aSI6ImNjMTFhZWFlYmNhMjJlNzIzYzRhZDE5ZTQzNTgxNmE5ZGM4MTllMjk4OGUyMzZmYTUzYjMwNDUyYTQ2YzhkZDg2NjVlYTU4ZGJmYmY0MTIwIiwiaWF0IjoxNTMzNzYwNjk1LCJuYmYiOjE1MzM3NjA2OTUsImV4cCI6MTU2NTI5NjY5NSwic3ViIjoiMSIsInNjb3BlcyI6W119.OSu3q5Gxj6Sad5B44J1kUTHs0H9Yc86Hw0oXtm-CmXyO_NirIX3oVxvEsACGpn-4gMMFOx61pJ4mb43pTg9dhIgmgDmywv5mkzRC-pLd5PiSaq4YpxFxlbk_rXZWDXGgGeLwh9iZl7-ByusECeKdn0LrqE3X0XrEehU25OLPI-lDq_hREVMV-eE4zTAunCbhLGMbNCMYZuvEB8NwBhKZSpdoIGS1buZmiUCupUTajgkgfMAVup2ym45s_0eIPvLjcDZgVvpaUgkvUBUPVcEoz-kkL7BTQjmgz0aPLhWYA116pa8pU_lwzuBzU7T85FCy6Mqlas6sg2aGI5RFhcWpFrNHvenNJ7Hd3PlgZHj5bHXpEmQtu93-50Z1tkG4h-wOZ9vxV9WHvDDRzfUg5aivqJtje1dLVLkyb2Eov_gpxhJWHSeAK3laN7_K0YL_gXN0lPey8kMsSuX74rPlOuiKZXsooYoP2VU_4EMxJgBPtUjuBq4o4RqZulFQljLUN02iPaevL1c3Q9LBlXr81O6qhKTjRZ4M3fdxjRkODgBnarQhGdGTnpwSnMn1UtUvjjTJKlnrRxwj4nsZCQI06YHXB06GOV85-5ChB6-c1xFa_XpeAvmftgz9xSKCxdlvwyQRU3NYpKd0eSJedVFEniHgjjwIhg4KYillScIrgFoo5NI

服务器令牌的末尾缺少64个字符。


我正在尝试从我的iOS应用发送带有URL中几个查询参数的GET请求。在添加新参数deviceToken之前,一切工作正常。之后,服务器以身份验证失败响应。最奇怪的是:我同时记录了auth令牌和URL字符串,并且可以成功地从Postman发出完全相同的请求,而没有任何auth错误。

此代码收到失败的身份验证响应(请注意,queryString包含deviceToken):

let escapedDeviceToken = deviceToken.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) ?? ""
let queryString = "latitude=\(location.coordinate.latitude)&longitude=\(location.coordinate.longitude)&deviceToken=\(escapedDeviceToken)"
let urlString = "\(account.serverAddress)?\(queryString)"
print("--- URL string \(account.authToken) \(urlString)")

let url = URL.init(string: urlString)!
var request = URLRequest(url: url)
request.setValue(account.authToken, forHTTPHeaderField: "Authorization")

print("--- Sending location update")
let dataTask = URLSession.shared.dataTask(with: request) {data, response, error in
  if let response = response {
    print("--- response \(response.debugDescription)")
  }
  if let error = error {
    print("--- Location update failed \(error.localizedDescription)")
  } else if let data = data {
    print("--- Location update success %@", data)
  }
}

dataTask.resume()

它将记录此URL和身份验证令牌:

--- URL string 
Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImNjMTFhZWFlYmNhMjJlNzIzYzRhZDE5ZTQzNTgxNmE5ZGM4MTllMjk4OGUyMzZmYTUzYjMwNDUyYTQ2YzhkZDg2NjVlYTU4ZGJmYmY0MTIwIn0.eyJhdWQiOiIxMCIsImp0aSI6ImNjMTFhZWFlYmNhMjJlNzIzYzRhZDE5ZTQzNTgxNmE5ZGM4MTllMjk4OGUyMzZmYTUzYjMwNDUyYTQ2YzhkZDg2NjVlYTU4ZGJmYmY0MTIwIiwiaWF0IjoxNTMzNzYwNjk1LCJuYmYiOjE1MzM3NjA2OTUsImV4cCI6MTU2NTI5NjY5NSwic3ViIjoiMSIsInNjb3BlcyI6W119.OSu3q5Gxj6Sad5B44J1kUTHs0H9Yc86Hw0oXtm-CmXyO_NirIX3oVxvEsACGpn-4gMMFOx61pJ4mb43pTg9dhIgmgDmywv5mkzRC-pLd5PiSaq4YpxFxlbk_rXZWDXGgGeLwh9iZl7-ByusECeKdn0LrqE3X0XrEehU25OLPI-lDq_hREVMV-eE4zTAunCbhLGMbNCMYZuvEB8NwBhKZSpdoIGS1buZmiUCupUTajgkgfMAVup2ym45s_0eIPvLjcDZgVvpaUgkvUBUPVcEoz-kkL7BTQjmgz0aPLhWYA116pa8pU_lwzuBzU7T85FCy6Mqlas6sg2aGI5RFhcWpFrNHvenNJ7Hd3PlgZHj5bHXpEmQtu93-50Z1tkG4h-wOZ9vxV9WHvDDRzfUg5aivqJtje1dLVLkyb2Eov_gpxhJWHSeAK3laN7_K0YL_gXN0lPey8kMsSuX74rPlOuiKZXsooYoP2VU_4EMxJgBPtUjuBq4o4RqZulFQljLUN02iPaevL1c3Q9LBlXr81O6qhKTjRZ4M3fdxjRkODgBnarQhGdGTnpwSnMn1UtUvjjTJKlnrRxwj4nsZCQI06YHXB06GOV85-5ChB6-c1xFa_XpeAvmftgz9xSKCxdlvwyQRU3NYpKd0eSJedVFEniHgjjwIhg4KYillScIrgFoo5NI 
http://192.168.1.61:80/api/updateLocation?latitude=44.0478080936615&longitude=-123.089300322125&deviceToken=fxdyzROI-vs%3AAPA91bFAdN3IR2bAxBS4rihVUCWsA1njO6RDgZ0fBDJRWvRisEKJz9I1ZTmeN6gsV85Dmg-0ZtGGqz9DSWmjZjqmyRrZ4feVBgUNPtfjALCZJM7hyScEyy02YixrW9zgcOK8sSW0JvFSrzpiPWYfdUZOt8gmU-8-NQ

这是我在Laravel服务器上看到的:

ERROR: exception 'League\OAuth2\Server\Exception\OAuthServerException' with message 'The resource owner or authorization server denied the request.' in /Users/james/projects/GoNoteDev/server/vendor/league/oauth2-server/src/Exception/OAuthServerException.php:165
Stack trace:
  0 ./vendor/league/oauth2-server/src/AuthorizationValidators/BearerTokenValidator.php(53): League\OAuth2\Server\Exception\OAuthServerException::accessDenied('Access token co...')
  1 ./vendor/league/oauth2-server/src/ResourceServer.php(82): League\OAuth2\Server\AuthorizationValidators\BearerTokenValidator->validateAuthorization(Object(Zend\Diactoros\ServerRequest))
  2 ./vendor/laravel/passport/src/Guards/TokenGuard.php(110): League\OAuth2\Server\ResourceServer->validateAuthenticatedRequest(Object(Zend\Diactoros\ServerRequest))
  3 ./vendor/laravel/passport/src/Guards/TokenGuard.php(90): Laravel\Passport\Guards\TokenGuard->authenticateViaBearerToken(Object(Illuminate\Http\Request))
  4 ./vendor/laravel/passport/src/PassportServiceProvider.php(251): Laravel\Passport\Guards\TokenGuard->user(Object(Illuminate\Http\Request))
  5 [internal function]: Laravel\Passport\PassportServiceProvider->Laravel\Passport\{closure}(Object(Illuminate\Http\Request))
  6 ./vendor/laravel/framework/src/Illuminate/Auth/RequestGuard.php(55): call_user_func(Object(Closure), Object(Illuminate\Http\Request))
  7 ./app/Http/Middleware/AuthApi.php(13): Illuminate\Auth\RequestGuard->user(Object(Illuminate\Http\Request))
  8 ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(148): App\Http\Middleware\AuthApi->handle(Object(Illuminate\Http\Request), Object(Closure))
  9 ./vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
  10 ./vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(41): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
  11 ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(148): Illuminate\Routing\Middleware\SubstituteBindings->handle(Object(Illuminate\Http\Request), Object(Closure))
  12 ./vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
  13 ./vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php(49): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
  14 ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(148): Illuminate\Routing\Middleware\ThrottleRequests->handle(Object(Illuminate\Http\Request), Object(Closure), '1000', '1')
  15 ./vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
  16 ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(102): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
  17 ./vendor/laravel/framework/src/Illuminate/Routing/Router.php(561): Illuminate\Pipeline\Pipeline->then(Object(Closure))
  18 ./vendor/laravel/framework/src/Illuminate/Routing/Router.php(520): Illuminate\Routing\Router->runRouteWithinStack(Object(Illuminate\Routing\Route), Object(Illuminate\Http\Request))
  19 ./vendor/laravel/framework/src/Illuminate/Routing/Router.php(498): Illuminate\Routing\Router->dispatchToRoute(Object(Illuminate\Http\Request))
  20 ./vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(174): Illuminate\Routing\Router->dispatch(Object(Illuminate\Http\Request))
  21 ./vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(30): Illuminate\Foundation\Http\Kernel->Illuminate\Foundation\Http\{closure}(Object(Illuminate\Http\Request))
  22 ./app/Http/Middleware/Cors.php(30): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
  23 ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(148): App\Http\Middleware\Cors->handle(Object(Illuminate\Http\Request), Object(Closure))
  24 ./vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
  25 ./vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(30): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
  26 ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(148): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle(Object(Illuminate\Http\Request), Object(Closure))
  27 ./vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
  28 ./vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(30): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
  29 ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(148): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle(Object(Illuminate\Http\Request), Object(Closure))
  30 ./vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
  31 ./vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
  32 ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(148): Illuminate\Foundation\Http\Middleware\ValidatePostSize->handle(Object(Illuminate\Http\Request), Object(Closure))
  33 ./vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
  34 ./vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php(46): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
  35 ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(148): Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode->handle(Object(Illuminate\Http\Request), Object(Closure))
  36 ./vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
  37 ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(102): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
  38 ./vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(149): Illuminate\Pipeline\Pipeline->then(Object(Closure))
  39 ./vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(116): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(Object(Illuminate\Http\Request))
  40 ./public/index.php(54): Illuminate\Foundation\Http\Kernel->handle(Object(Illuminate\Http\Request))
  41 ./server.php(21): require_once('/Users/james/pr...')
  42 {main}

然后我从iOS日志中获取确切的身份验证令牌和URL,并将其粘贴到邮递员中:

Postman success

成功。邮递员请求后,我的Laravel服务器日志:

[2018-08-08 14:17:38] INFO: -123.08930032212 44.047808093662 fxdyzROI-vs:APA91bFAdN3IR2bAxBS4rihVUCWsA1njO6RDgZ0fBDJRWvRisEKJz9I1ZTmeN6gsV85Dmg-0ZtGGqz9DSWmjZjqmyRrZ4feVBgUNPtfjALCZJM7hyScEyy02YixrW9zgcOK8sSW0JvFSrzpiPWYfdUZOt8gmU-8-NQ 2
[2018-08-08 14:17:38] INFO: Sending PN to fxdyzROI-vs:APA91bFAdN3IR2bAxBS4rihVUCWsA1njO6RDgZ0fBDJRWvRisEKJz9I1ZTmeN6gsV85Dmg-0ZtGGqz9DSWmjZjqmyRrZ4feVBgUNPtfjALCZJM7hyScEyy02YixrW9zgcOK8sSW0JvFSrzpiPWYfdUZOt8gmU-8-NQ
[2018-08-08 14:17:39] INFO: Success

这是iOS HTTP代码中的错误吗?为什么只有从iOS发送请求时才会失败?看来iOS正在剥离或破坏我的Authorization标头。

还有两件事:

  • 服务器上的身份验证中间件未使用deviceToken参数。
  • 删除deviceToken参数会使请求始终成功。
  • &deviceToken=代替&someOtherNameHere=会导致相同的问题(似乎与deviceToken参数完全无关)。

0 个答案:

没有答案