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 ?? "")
}
})
ご覧のとおり、セッション構成とリクエストの両方でトークンを設定しようとしましたが、どれも機能していません。
これは機能しているようです:
// 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...
}
注:同僚が作成したコード。ジョンありがとう!
問題は、Authorization
を使用してhttpAdditionalHeaders
ヘッダーを変更していることです。これは、すべきではないことです。
Doc から
NSURLSessionオブジェクトは、HTTPプロトコルのさまざまな側面を処理するように設計されています。そのため、次のヘッダーは変更しないでください:Authorization、Connection、Host、Proxy-Authenticate、Proxy-Authorization、WWW-Authenticate
行の削除config.httpAdditionalHeaders = headers
で問題が解決するはずです。
私は同じことを見つけました:ヘッダーフィールド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からの参考文書 そんなものを読むのが好きなら.