web-dev-qa-db-ja.com

URLSessionがヘッダーの「Authorization」キーを渡さないSwift 4

URLRequestのヘッダーで認証キーを渡そうとしています。しかし、サーバー側ではキーは受信されません。郵便配達員から呼び出されたときと同じAPIが正常に機能しています。ヘッダー内の他のキーは正常に機能しており、認証キーもサーバー側に表示されます。

これが私のコードです:

let headers = [
    "authorization": "token abcd"
]

var request = URLRequest.init(url: NSURL(string:
    "http://127.0.0.1:7000/api/channels?filter=contributed")! as URL)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers
let config = URLSessionConfiguration.default
config.httpAdditionalHeaders = headers
let session = URLSession.init(configuration: config)

let dataTask = session.dataTask(with: request, completionHandler: { (data, response, error) -> Void in
    if (error != nil) {
        print(error ?? "")
    } else {
        let httpResponse = response as? HTTPURLResponse
        print(httpResponse ?? "")
    }
})

ご覧のとおり、セッション構成とリクエストの両方でトークンを設定しようとしましたが、どれも機能していません。

9
Santosh

これは機能しているようです:

// Set the security header
private var credentials: String {
    return "\(participantId):\(password)"
}

private var basicAuthHeader: String {
    return "Basic \(credentials)"
}

func getSettings(participantId: Int, password: String) -> Bool {

    self.participantId = participantId
    self.password = password

    let path = "/settings/\(participantId)"
    guard let url = URL(string: "\(BASE_URL)\(path)") else {
        Log.e("Invalid URL string, could not convert to URL")
        return false
    }

    var urlRequest = URLRequest(url: url)
    urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
    urlRequest.setValue(basicAuthHeader, forHTTPHeaderField: "Authorization")
    urlRequest.setValue(APP_FILE_NAME, forHTTPHeaderField: "User-Agent")

    // This is a synchronous wrapper extension around URLSession.dataTask()
    let (data, response, error) = URLSession.shared.synchronousDataTask(with: urlRequest)
    // Process the result...
}

注:同僚が作成したコード。ジョンありがとう!

6

問題は、Authorizationを使用してhttpAdditionalHeadersヘッダーを変更していることです。これは、すべきではないことです。

Doc から

NSURLSessionオブジェクトは、HTTPプロトコルのさまざまな側面を処理するように設計されています。そのため、次のヘッダーは変更しないでください:Authorization、Connection、Host、Proxy-Authenticate、Proxy-Authorization、WWW-Authenticate

行の削除config.httpAdditionalHeaders = headersで問題が解決するはずです。

0
sleepwalkerfx

私は同じことを見つけました:ヘッダーフィールドAuthorizationを設定してもうまくいかなかっただけです。

ここに私が解決した解決策があります(うまくいきます):

現在のクラスにURLSessionDelegateプロトコルを追加しました。残念ながら、これはNSObjectから継承することを意味します。

次に、URLSessionを定義するときに、そのデリゲートを 'self'に設定しました。

最後に、認証チャレンジハンドラを提供します。

コードでは、これはすべて次のようになります。

public class SomeHTTPTask: NSObject, URLSessionDelegate {
    public init() {
        ... initialize variables ...
        super.init()
        ... now you are free to call methods on self ...
    }

    public func httpTask(withURL url: URL) {
        let request = URLRequest(url: url)
        ... set up request ...
        let config = URLSessionConfiguration.default
        let session = URLSession(configuration: config, delegate: self, delegateQueue: nil)
        let task = session.dataTask(with: request) {data, response, error in
            ... now you have a result ...
        }
    }

    public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        guard let user = Credentials.sharedInstance.userId, let password = Credentials.sharedInstance.password else {
            completionHandler(.performDefaultHandling, nil)
            return
        }
        let userCredential = URLCredential(user: user,
                                           password: password,
                                           persistence: .permanent)
        completionHandler(.useCredential, userCredential)
    }

}

うまくいけば、ビットとピースは自明です。可能であれば、資格情報を提供するのは単なる認証チャレンジハンドラです。基礎となるURLSessionは、NTLMまたは基本認証などの種類の詳細を処理します。

結局、これは固い解決策のようです。少なくとも、それは私にとってはうまくいった。

これがいいものだ Appleからの参考文書 そんなものを読むのが好きなら.

0
Anthony Taylor