使用 JSON 进行基本身份验证

Posted

技术标签:

【中文标题】使用 JSON 进行基本身份验证【英文标题】:Basic authentication with JSON 【发布时间】:2018-01-08 10:45:31 【问题描述】:

我请求的 JSON 页面需要字符串类型的密码和用户名。用户名和密码属于开发人员......顺便说一句,它能够访问页面,我只是无法通过身份验证。

这是 api 网址:https://api.intrinio.com/prices?identifier=AAPL

如果我遗漏了一些信息或代码,请告诉我,我会提供。

class ViewController: UIViewController, UITextFieldDelegate, UITableViewDelegate, UITableViewDataSource 

    //MARK: - Outlets
    @IBOutlet weak var labelTwo: UILabel!
    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var tickerTextField: UITextField!

    //MARK: - Properties
    let userPasswordString = ""
    let userPassword = ""

    //MARK: - View Did Load
    override func viewDidLoad() 
        tickerTextField.textColor = UIColor.lightGray
        tickerTextField.text = "Search Ticker"
        tickerTextField.delegate = self

        let jsonUrlString = "https://api.intrinio.com/prices?identifier=\(ticker)"
        print(jsonUrlString)
        guard let url = URL(string: jsonUrlString) else  return 
        URLSession.shared.dataTask(with: url)  (data, response, err) in
            let dataAsString = String(data: data!, encoding: .utf8)
            print(dataAsString!)
            guard let data = data else  return 
            do 
                let jsonDecoder = JSONDecoder()
                let tickerPrice = try jsonDecoder.decode(TickerPrice.self, from: data)
                DispatchQueue.main.async 
                   print(tickerPrice.name)
                
             catch let jsonErr 
                print("Error serielaising jason", jsonErr)
            
            .resume()

    

【问题讨论】:

docs.intrinio.com/#authentication 您需要添加带有登录名/密码的标题。 如果我理解正确(考虑逻辑,而不是“未包装的 Swift 错误编码等):var request = URLRequest.init(url: url!); let userName = "API_USERNAME"; let password = "API_PASSWORD"; let toEncode = "\(userName):\(password)"; let encoded = toEncode.data(using: .utf8)?.base64EncodedString(); request.addValue("Basic \(encoded!)", forHTTPHeaderField: "Authorization")。然后URLSession.shared.dataTask(with: request) 而不是(with: url) 【参考方案1】:

来自documentation:

Private 授权您访问 Intrinio API:

// With shell, you must include the username and 
// password header
curl "https://api.intrinio.com/data_point?identifier=AAPL&item=close_price"
  -u "API_USERNAME:API_PASSWORD"

// With the '-u' option in curl, it will automatically
// convert the username and password into the 
// appropriate header. If you do not use this 
// option or it is not available to you, you must 
// include a header with the basic auth credentials 
// included as base64 encoded.
curl "https://api.intrinio.com/data_point?identifier=AAPL&item=close_price"
  -H "Authorization: Basic $BASE64_ENCODED(API_USERNAME:API_PASSWORD)"

对于私有/可信环境,使用基于 HTTPS 的基本身份验证。

您可以在您的帐户页面上找到您的 API 用户名和 API 密码。 您必须在每个请求中包含这些凭据,以便 获得对 API 的访问权限。

要在您的 HTTPS 请求中包含凭据,请指定 授权标头,值为 Basic (key),将 (key) 替换为 Base-64 编码字符串 API_USERNAME:API_PASSWORD。

如果您的凭据未经授权,则状态码 401 将是 返回。

您必须将 API_USERNAME 和 API_PASSWORD 替换为您的 API 密钥 在您的 API 管理仪表板上找到。

为此,您需要使用URLRequest 而不仅仅是URL

//Create URLRequest
var request = URLRequest.init(url: url!)

//Create Header according to the documentation
let userName = "API_USERNAME" //Need to be replaced with correct value
let password = "API_PASSWORD" //Need to be replaced with correct value
let toEncode = "\(userName):\(password)" //Form the String to be encoded
let encoded = toEncode.data(using: .utf8)?.base64EncodedString()

//Add the header value
request.addValue("Basic \(encoded!)", forHTTPHeaderField: "Authorization")

//Perform the task with the request instead of previously the URL
URLSession.shared.dataTask(with: request)//The rest of your code

旁注,我没有做guard letif let,我在需要时丑陋地打开了包装。这是为了展示主要逻辑和 CocoaTouch API,而不是其他任何东西,尤其是因为我不是 Swift 开发人员。

【讨论】:

以上是关于使用 JSON 进行基本身份验证的主要内容,如果未能解决你的问题,请参考以下文章

AFNetworking 2 使用 AFHTTPRequestOperation 进行身份验证

无法使用基本身份验证进行身份验证

使用 Devise 1.3 对 JSON 登录请求进行身份验证

使用基于 SAML 的基本身份验证进行身份验证?

使用 fetch 进行基本身份验证(或任何身份验证)

使用 nginx 进行基本身份验证,然后在 PHP 中进行摘要身份验证失败