Closed
Description
Using
PODS:
- Alamofire (2.0.1)
I have this strange issue, that the Authorization-Header isn't sent for some requests.
Just upgraded to Alamofire 2.0.1 from 1.3. Had the same problem with the 1.3 on iOS 9 - one specific request does not get the Header sent...
I tried both ways of setting the header. a) Using a dedicated Manager created with:
func createManagerWithAuthHeader(authHeader:String) -> Manager {
var addedHeaders = Manager.defaultHTTPHeaders
addedHeaders["Authorization"] = authHeader
NSLog("Authorization-Header: \(authHeader)")
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
configuration.HTTPAdditionalHeaders = addedHeaders
return Manager(configuration: configuration)
}
Now I just keep the different values for Authentication and apply them depending on the route:
// Router to generate Requests
enum Router: URLRequestConvertible {
static let BASE_URL = "************"
// Possible Requests
....
case Category(String)
case Criterias(String)
....
var URLRequest: NSMutableURLRequest {
let (path, method, userAuth, parameters, encoder): (String, String, Bool, [String: AnyObject], Alamofire.ParameterEncoding) = {
switch self {
.....
case .Category(let catId):
return ("/categories/\(catId)/", "GET", false, [:], Alamofire.ParameterEncoding.URL)
case .Criterias(let catId):
return ("/categories/\(catId)/criteria", "GET", false, [:], Alamofire.ParameterEncoding.URL)
.....
}
}()
let requestUrl = NSURL(string: Router.BASE_URL)
let request = NSMutableURLRequest(URL: requestUrl!.URLByAppendingPathComponent(path))
request.HTTPMethod = method
let authHeader = userAuth ? Client.sharedInstance.userAuthHeader : Client.sharedInstance.clientAuthHeader
request.setValue(authHeader, forHTTPHeaderField: "Authorization")
let encoding = encoder
let encodedRequest = encoding.encode(request, parameters: parameters).0
return encodedRequest
}
}
The funny thing is, that the call with .Category
works. Here's the code:
func getCategory(categoryId:String, completion: (Category?, ErrorType?) -> Void) {
let route = Router.Category(categoryId)
let request = route.URLRequest
let authHeader = request.valueForHTTPHeaderField("Authorization")
NSLog("getCategory: \(request) - \(authHeader)")
Alamofire.request(route)
.responseObject { (category:Category?, meta:JoixesMetaData?, error: ErrorType?) -> Void in
if error != nil || category == nil {
completion(nil, error)
}
else {
completion(category, nil)
}
}
}
First request on the wire (Wireshark):
GET /api/v1/categories/_VWypVvLTnWSM7kcK2NuJAl_/? HTTP/1.1
Host: ****
Connection: keep-alive
Accept: */*
User-Agent: Joixes/com.joixes.Joixes (3; OS Version 9.0 (Build 13A340))
Accept-Language: en-US;q=1.0
Authorization: Basic Umctb25nQkxRYmF......
Accept-Encoding: gzip;q=1.0,compress;q=0.5
HTTP/1.0 200 OK
Date: Fri, 18 Sep 2015 17:01:54 GMT
Server: WSGIServer/0.2 CPython/3.4.3
Allow: GET, HEAD, OPTIONS
X-Frame-Options: SAMEORIGIN
Vary: Accept
Content-Type: application/json
{"data":{"uid":"_VWypVvLTnWSM7kcK2NuJAl_","name":"Clutches","longName":"Women, Clutches","parentCategory":"TF6thQUmTyiwJt10QsmLJgdC","verticalCategory":"x23Un1lcSGSTideM2RQdJw7N","isFindable":true,"hasChild":false,"childCategories":[]},"meta":{"detail":"Success.","code":200,"success":true}}
And with Criterias it does not work:
func getCriteriasForCategory(categoryId:String, completion: ([BaseFilterCriteria], ErrorType?) -> Void) {
let route = Router.Criterias(categoryId)
let request = route.URLRequest
let authHeader = request.valueForHTTPHeaderField("Authorization")
NSLog("getCriteriasForCategory: \(request) - \(authHeader)")
Alamofire.request(route)
.responseJoixes { (jxResponse, error) -> Void in
NSLog("getCriteriasForCategory: jxResponse: \(jxResponse)")
var criterias:[BaseFilterCriteria] = []
if let criteriaData = jxResponse?.data as? [AnyObject] {
criterias = criteriaData.map { return CriteriaFactory.parseCriteria($0 as! [String:AnyObject]) }
}
completion(criterias, error)
}
}
Note: The Authorization-Header in the variable authHeader is correct!! With both requests the exact same value
On the wire there is not :
GET /api/v1/categories/_VWypVvLTnWSM7kcK2NuJAl_/criteria/ HTTP/1.1
Host: *****
Accept-Language: en-US;q=1.0
User-Agent: Joixes/com.joixes.Joixes (3; OS Version 9.0 (Build 13A340))
Accept: */*
Accept-Encoding: gzip;q=1.0,compress;q=0.5
Connection: keep-alive
HTTP/1.0 401 UNAUTHORIZED
Date: Fri, 18 Sep 2015 17:02:03 GMT
Server: WSGIServer/0.2 CPython/3.4.3
Allow: GET, OPTIONS
WWW-Authenticate: Token realm=api
X-Frame-Options: SAMEORIGIN
Vary: Accept
Content-Type: application/json
{"data":null,"meta":{"detail":"Authentication credentials were not provided.","code":401,"success":false}}
Any Hints where the Header-Value could get lost??
Metadata
Metadata
Assignees
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
pramodsharma403 commentedon Sep 18, 2015
@eburi Hi Please use this code to send Authorization-Header
jaunesarmiento commentedon Sep 19, 2015
Had this same issue before updating to Xcode 7. I was running my app with Alamofire 1.3 on iOS 9 and authorization headers were not being received by my server. I did what @pramodsharma403 to fix/monkey-patch this issue.
I'd still want to set the headers with
HTTPAdditionalHeaders
though.cnoon commentedon Sep 19, 2015
Authorization
headers should not be set in theHTTPAdditionalHeaders
dictionary on theNSURLSessionConfiguration
. Instead, anAuthorization
header should be appended to each individual request. This is the recommendation of both the ASF as well as Apple.eburi commentedon Sep 21, 2015
@pramodsharma403 How can I combine this with a Router? I have a lot of different requests and I would really like to use the router.
I implemented the URLRequestConvertible, I create a there an NSMutableURLRequest and I set the header on this request.
When you look at this code:
and this is the console output:
Note: I put where there is sensitive information (just a test-plattform anyway...)
I just don't understand this: How is the header not sent, when clearly present on the URLRequestConvertible. I also put a log message into
public func request(URLRequest: URLRequestConvertible) -> Request
in Alamofire/Manager.swift where it outputs basically the auth-header from the originalRequest-attribute on the DataTask. The value is still present there.From my point of view, I'm giving to Alamofire the exact same thing as with any other request. With any other request it's just fine. But with this request, the Header is simply not sent.
I have no cloud what else could influence this....
cnoon commentedon Sep 21, 2015
@eburi which version of Alamofire are you using? Alamofire 2.0.1 contains a fix that should solve this issue for you.
eburi commentedon Sep 21, 2015
pod install says:
But I just found out what the problem is, thanks to Wireshark! The request to the server does have the Authorization-Header set, but the server is replying with a 301 MOVED PERMANENTLY, and the subsequent request - I don't know who's doing this - is sent to the new location BUT without the headers from the original request! Hence the unauthorised response!
Since this "MOVED PERMANENTLY" is not visible to me as Alamofire-user, I was not aware of this.
It's actually very small change I missed in the API-Docs from the server I'm calling.
The endpoint used to be
/criterias
and it's now "MOVED" to/criterias/
...It would be great, if I would get a notice or Log-Message for 301 return-codes.
And it would be great if these Redirects were to be followed with the headers for the original request.
rolandoasmat commentedon Apr 5, 2016
@eburi So this was fixed by pointing to the correct endpoint and the Router worked accordingly?
phiberjenz commentedon Aug 4, 2016
I have the same problem. Trying to send a request with an Authorization header set on the NSMutableURLRequest. Header is visible on the request object in the completion handler, but not visible in the actual request sent to the server (no Authorization header when sending request through Charles Proxy). Any ideas?
simonnarang commentedon Aug 4, 2016
@phiberjenz The headers are sent in the URL body, not in the actual URL for a post request, in a get request, if you want them to show up in the actual URL you put them in the body parameter like you would in the headers parameter(as an array)
cnoon commentedon Aug 4, 2016
@phiberjenz and @simonnarang: please refer to the info in #798 for more info on these findings. It walks you through the various options available to you when this happens.
Cheers. 🍻