I used authenticate() method on dataRequest:
defaultManager.request(address).authenticate(user: username, password: password, persistence: .none).responseString {
response in ... }
Passed data (username and password) contained only ASCII characters.
I expected that Authorization header will be added to the request.
I checked response.request.allHTTPHeaderFields and this dictionary is empty. Also the server is returning "No credentials were included in request".
Server is accepting proper authorization header (details in Fix section below).
I tried to debug this problem and found that trying to po credential.persistance inside method (Request.swift line 167) :
open func authenticate(
user: String,
password: String,
persistence: URLCredential.Persistence = .forSession)
-> Self
resulted in the following error (tested it few times):
'pthread_rwlock_rdlock(&rwlock)' failed with error 'EDEADLK'(11)
2017-08-08 10:11:21.898723+0200 AppName[2391:1931414] 'pthread_rwlock_rdlock(&rwlock)' failed with error 'EDEADLK'(11)
expression produced error: error: Execution was interrupted, reason: signal SIGABRT.
The process has been returned to the state before expression evaluation.
Alamofire version: 4.5.0
Xcode version: Version 8.3.3 (8E3004b)
Swift version: 3.1 (swiftlang-802.0.53 clang-802.0.42)
Platform(s) running Alamofire: iPhone 5S, iOS 10.3.2 (14F89)
macOS version running Xcode: 10.12.5 (16F73)
I fixed it by using DataRequest.authorizationHeader and manually passing this header to headers to request (it works), but I think that it can be a bug and it's worth submitting.
(maybe there were some other - I've found this two)
This is the intended behavior of authenticate. As you can see in our documentation, the authenticate function is used to _respond_ to requests for authentication from the server, not for adding an auth header that's needed for every request. If your server had responded in such a way as to trigger this response (this is handled by the underlying URLSession), then your implementation would've been correct. Using the authorizationHeader method to generate a header and add it to all requests is the correct way to solve this problem. It's easier when using a router or other pattern to generate requests, so you aren't manually adding the header all of the time, which is why we suggest the router in the first place.
That said, we'll be looking into our header APIs for Alamofire 5 (#2232). If you have any concrete ideas for APIs in this area, feel free to open another issue outlining your proposal.
Just to chime in it'd be super great if the docs outlined this — right now they say authenticate "associates an HTTP Basic Auth credential with the request" which sounds a lot like "adds an Authorization HTTP header". Will see if I can help out with this somehow!
Most helpful comment
This is the intended behavior of
authenticate. As you can see in our documentation, theauthenticatefunction is used to _respond_ to requests for authentication from the server, not for adding an auth header that's needed for every request. If your server had responded in such a way as to trigger this response (this is handled by the underlyingURLSession), then your implementation would've been correct. Using theauthorizationHeadermethod to generate a header and add it to all requests is the correct way to solve this problem. It's easier when using a router or other pattern to generate requests, so you aren't manually adding the header all of the time, which is why we suggest the router in the first place.That said, we'll be looking into our header APIs for Alamofire 5 (#2232). If you have any concrete ideas for APIs in this area, feel free to open another issue outlining your proposal.