How to set Authorization to URlRequest in swift 3.0

Hi,

I'm getting strange behaviour when posting to get response from server which requires Basic Authorization.my token gets gets expired after every two hours.Every things works fine but some times i dn't knw but getting reponse from server "Parameter not null" error.i debuged there is nothing going null.i go through document-https://developer.apple.com/reference/foundation/nsmutableurlrequest

where mentioned some http headers could not be modified using methods

addValue(_:forHTTPHeaderField:)
or
setValue(_:forHTTPHeaderField:)

i cannot figure where is going wrong and more when i'm setting Content & Accept type for json

addValue(_:forHTTPHeaderField:) workds gud to set authorization and for xml  setValue(_:forHTTPHeaderField:) works but still .sometimes  they breaks.Below is my code
//for json rsponse
func callWebserviceForJSON(_ urlStr: String ,callback:@escaping (_ data: Dictionary<String,String>) -> Void)
    {
          
        let url1 = URL(string: urlStr)
        var request = URLRequest(url: url1!)
      
         let tokenId = fileMgr.getCacheData(constants.defaultsKeys.TOKEN_KEY) as! String
      
        let authorizationKey = "Basic ".appending(tokenId)
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("application/json", forHTTPHeaderField: "Accept")
        request.addValue(authorizationKey, forHTTPHeaderField: "Authorization")
        request.timeoutInterval = 20000.0
      
        var dict = Dictionary<String,String>()
        let task = URLSession.shared.dataTask(with: request)
          {
            data, response, error -> Void in
     }
//for xml response

/
    func callPostWebservice(_ urlStr: String, callback:@escaping (_ data: Dictionary<String,String>) -> Void)
    {
       
         
       
        let url1 = URL(string: urlStr)
        var request = URLRequest(url: url1!)
       
         let tokenId = fileMgr.getCacheData(constants.defaultsKeys.TOKEN_KEY) as! String
       
        print("tokenId >> \(tokenId) , urlStr >> \(urlStr)")
        request.httpMethod = "POST"
        request.addValue("application/xml", forHTTPHeaderField: "Content-Type")
        request.addValue("application/xml", forHTTPHeaderField: "Accept")
        request.setValue("Basic \(tokenId)", forHTTPHeaderField: "Authorization")
        request.timeoutInterval = 20000.0
       
        var dict = Dictionary<String,String>()
        let task = URLSession.shared.dataTask(with: request)
        {data, response, error  in }

Please advice

Post not yet marked as solved Up vote post of nitisha Down vote post of nitisha
16k views

Replies

I’m not sure what’s going on with your specific code but setting the

Authorization
header manually is not the right approach. Rather, you should set up your session to handle authentication challenges via the
-URLSession:task:didReceiveChallenge:completionHandler:
delegate callback.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

you are right but i've to set Authorization manually because i'm getting token in log in process,and it have to use that token for further post request.

please advice

Is there a working example of this anywhere?


I've implemented various kinds of authentication with the URLSession:task:didReceiveChallenge:completionHandler: callback, but every time I have tried to use it for plain old HTTP Basic Authentication I have found it difficult. The documentation sometimes gives the impression the API is only intended for responding to challenges (rather than volunteering credentials as part of the request). I always end up manually building the HTTP headers, which feels wrong.


What's the Right Way to do plain old HTTP Basic Auth with the URLSession and friends?

What's the Right Way to do plain old HTTP Basic Auth with the URLSession and friends?

The right way to handle Basic and Digest authentication is to implement the per-task authentication challenge handler and respond to those challenges. Pasted in below is a snippet.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
func basicAuthTrip(didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
    if challenge.previousFailureCount < 3 {
        let credential = URLCredential(user: "bbbb", password: "BBBB", persistence: .forSession)
        completionHandler(.useCredential, credential)
    } else {
        completionHandler(.cancelAuthenticationChallenge, nil)
    }
}

func digestAuthTrip(didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
    if challenge.previousFailureCount < 3 {
        let credential = URLCredential(user: "dddd", password: "DDDD", persistence: .forSession)
        completionHandler(.useCredential, credential)
    } else {
        completionHandler(.cancelAuthenticationChallenge, nil)
    }
}

func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {

    // Look for specific authentication challenges and dispatch those to various helper methods.
    //
    // IMPORTANT: It's critical that, if you get a challenge you weren't expecting,
    // you resolve that challenge with `.performDefaultHandling`.

    switch (challenge.protectionSpace.authenticationMethod, challenge.protectionSpace.host) {
        case (NSURLAuthenticationMethodHTTPBasic, "httpbin.org"):
            self.basicAuthTrip(didReceive: challenge, completionHandler: completionHandler)
        case (NSURLAuthenticationMethodHTTPDigest, "httpbin.org"):
            self.digestAuthTrip(didReceive: challenge, completionHandler: completionHandler)
        default:
            completionHandler(.performDefaultHandling, nil)
    }
}

That's very helpful for Basic and Digest.


But what about "Bearer <token>"?


I've been at this for a few hours, coding and googling, without any joy. I (and several other devs over the past couple years, apparently) would love to learn the secret incantations.


UPDATE: Ah. I guess you've already addressed this in https://forums.developer.apple.com/thread/89811