使用URLSession时出现401授权错误

时间:2020-09-18 20:42:25

标签: ios swift server

我正在尝试从需要用户/密码身份验证的应用服务器中检索JSON。有谁知道为什么不允许我进入服务器?我尝试包括带有所需凭据的授权标头,但仍然出现此错误。

func retrieveJSON(){
    let login = "login@mail.com"
    let password = "password"
    
    let url = NSURL(string: "http://server/admin/data.json")
    let request = NSMutableURLRequest(url: url! as URL)
    
    let config = URLSessionConfiguration.default
    let userPasswordString = "\(login):\(password)"
    let userPasswordData = userPasswordString.data(using: String.Encoding.utf8)
    let base64EncodedCredential = userPasswordData!.base64EncodedString()
    let authString = "Basic \(base64EncodedCredential)"
    config.httpAdditionalHeaders = ["Authorization" : authString]
    
    let session = URLSession(configuration: config)
    let task = session.dataTask(with: request as URLRequest) { (data, response, error) -> Void in
        debugPrint(response)
    }
    task.resume()
}

Response message with 401 error

Server authorization needed

1 个答案:

答案 0 :(得分:0)

您的网站似乎未使用“基本”身份验证。它似乎正在使用一些不同的身份验证方案,我们无法从HTML登录页面的图像中确定该方案。


如果使用的是“基本”身份验证(在您的特定情况下可能不使用),则可以稍微简化代码,删除NSURLNSMutableURLRequest,演员表等。 ,如果您要创建URLSession,则需要finishTasksAndInvalidate

func retrieveJSON() {
    let login = "login@mail.com"
    let password = "password"

    let url = URL(string: "http://server/admin/data.json")!
    let request = URLRequest(url: url)  // use `var` if you really need it to be mutable

    let config = URLSessionConfiguration.default
    let base64EncodedCredential = (login + ":" + password)
        .data(using: .utf8)!
        .base64EncodedString()
    config.httpAdditionalHeaders = ["Authorization": "Basic " + base64EncodedCredential]

    let session = URLSession(configuration: config)
    let task = session.dataTask(with: request) { data, response, error in
        debugPrint(response ?? "No response")
    }
    task.resume()
    session.finishTasksAndInvalidate()
}

或者,您可以自己调用Authorization来向请求添加身份验证标头,而不是自己构建CFHTTPMessageAddAuthentication标头。此外,除了将身份验证添加到请求本身之外,您不必创建自己的URLSession,但可以使用共享实例。

func retrieveJSON() {
    let login = "login@mail.com"
    let password = "password"

    let url = URL(string: "http://server/admin/data.json")!
    var request = URLRequest(url: url)
    request.updateBasicAuth(for: login, password: password)
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        debugPrint(response ?? "No response")
    }
    task.resume()
}

哪里

extension URLRequest {

    /// Update request for HTTP authentication
    ///
    /// - parameter username:        The username
    /// - parameter password:        The password
    /// - parameter authentication:  The type of authentication to be applied

    mutating func updateBasicAuth(for username: String, password: String, authentication: String = kCFHTTPAuthenticationSchemeBasic as String) {
        let message = CFHTTPMessageCreateRequest(kCFAllocatorDefault, httpMethod! as CFString, url! as CFURL, kCFHTTPVersion1_1).takeRetainedValue()
        if !CFHTTPMessageAddAuthentication(message, nil, username as CFString, password as CFString, authentication as CFString?, false) {
            print("authentication not added")
        }
        if let authorizationString = CFHTTPMessageCopyHeaderFieldValue(message, "Authorization" as CFString)?.takeRetainedValue() {
            setValue(authorizationString as String, forHTTPHeaderField: "Authorization")
        } else {
            print("didn't find authentication header")
        }
    }
}

但是,如果您的服务器使用其他身份验证方案,则对“基本”身份验证的改进在某种程度上是可行的。