Swift에서 HTTP 요청 + 기본 인증을 하는 방법
저는 기본 인증이 가능한 RESTFull 서비스를 가지고 있으며 iOS+swift에서 호출하고 싶습니다.이 요청에 대한 자격 증명을 어떻게 어디서 제공해야 합니까?
내 코드(죄송하지만 iOS/obj-c/swift를 이제 막 배우기 시작했습니다):
class APIProxy: NSObject {
var data: NSMutableData = NSMutableData()
func connectToWebApi() {
var urlPath = "http://xx.xx.xx.xx/BP3_0_32/ru/hs/testservis/somemethod"
NSLog("connection string \(urlPath)")
var url: NSURL = NSURL(string: urlPath)
var request = NSMutableURLRequest(URL: url)
let username = "hs"
let password = "1"
let loginString = NSString(format: "%@:%@", username, password)
let loginData: NSData = loginString.dataUsingEncoding(NSUTF8StringEncoding)
let base64LoginString = loginData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.fromMask(0))
request.setValue(base64LoginString, forHTTPHeaderField: "Authorization")
var connection: NSURLConnection = NSURLConnection(request: request, delegate: self)
connection.start()
}
//NSURLConnection delegate method
func connection(connection: NSURLConnection!, didFailWithError error: NSError!) {
println("Failed with error:\(error.localizedDescription)")
}
//NSURLConnection delegate method
func connection(didReceiveResponse: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {
//New request so we need to clear the data object
self.data = NSMutableData()
}
//NSURLConnection delegate method
func connection(connection: NSURLConnection!, didReceiveData data: NSData!) {
//Append incoming data
self.data.appendData(data)
}
//NSURLConnection delegate method
func connectionDidFinishLoading(connection: NSURLConnection!) {
NSLog("connectionDidFinishLoading");
}
}
에서 자격 증명을 제공하는 경우URLRequest
예를 들어, 스위프트 3의 경우와 같습니다.
let username = "user"
let password = "pass"
let loginString = String(format: "%@:%@", username, password)
let loginData = loginString.data(using: String.Encoding.utf8)!
let base64LoginString = loginData.base64EncodedString()
// create the request
let url = URL(string: "http://www.example.com/")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")
// fire off the request
// make sure your class conforms to NSURLConnectionDelegate
let urlConnection = NSURLConnection(request: request, delegate: self)
또는NSMutableURLRequest
Swift 2에서:
// set up the base64-encoded credentials
let username = "user"
let password = "pass"
let loginString = NSString(format: "%@:%@", username, password)
let loginData: NSData = loginString.dataUsingEncoding(NSUTF8StringEncoding)!
let base64LoginString = loginData.base64EncodedStringWithOptions([])
// create the request
let url = NSURL(string: "http://www.example.com/")
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")
// fire off the request
// make sure your class conforms to NSURLConnectionDelegate
let urlConnection = NSURLConnection(request: request, delegate: self)
swift 4:
let username = "username"
let password = "password"
let loginString = "\(username):\(password)"
guard let loginData = loginString.data(using: String.Encoding.utf8) else {
return
}
let base64LoginString = loginData.base64EncodedString()
request.httpMethod = "GET"
request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")
//인증 기반 64 인코딩 문자열 만들기
let PasswordString = "\(txtUserName.text):\(txtPassword.text)"
let PasswordData = PasswordString.dataUsingEncoding(NSUTF8StringEncoding)
let base64EncodedCredential = PasswordData!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.Encoding64CharacterLineLength)
//let base64EncodedCredential = PasswordData!.base64EncodedStringWithOptions(nil)
//인증 URL 생성
let urlPath: String = "http://...../auth"
var url: NSURL = NSURL(string: urlPath)
//기본 인증 요청 만들기 및 초기화
var request: NSMutableURLRequest = NSMutableURLRequest(URL: url)
request.setValue("Basic \(base64EncodedCredential)", forHTTPHeaderField: "Authorization")
request.HTTPMethod = "GET"
//다음 방법 중 하나를 사용할 수 있습니다.
//1 NSURLConnectionDataDelegate를 사용한 URL 요청
let queue:NSOperationQueue = NSOperationQueue()
let urlConnection = NSURLConnection(request: request, delegate: self)
urlConnection.start()
//2 비동기 요청을 포함한 URL 요청
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {(response, data, error) in
println(NSString(data: data, encoding: NSUTF8StringEncoding))
}
//2 URL 요청 및 비동기 요청 및 json 출력
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler:{ (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
var err: NSError
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
println("\(jsonResult)")
})
//3 동기식 요청을 포함한 URL 요청
var response: AutoreleasingUnsafePointer<NSURLResponse?>=nil
var dataVal: NSData = NSURLConnection.sendSynchronousRequest(request, returningResponse: response, error:nil)
var err: NSError
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(dataVal, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
println("\(jsonResult)")
//4 NSURL 세션을 사용한 URL 요청
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let authString = "Basic \(base64EncodedCredential)"
config.HTTPAdditionalHeaders = ["Authorization" : authString]
let session = NSURLSession(configuration: config)
session.dataTaskWithURL(url) {
(let data, let response, let error) in
if let httpResponse = response as? NSHTTPURLResponse {
let dataString = NSString(data: data, encoding: NSUTF8StringEncoding)
println(dataString)
}
}.resume()
요청을 변경하면 치명적인 오류가 발생할 수 있습니다.서버 요청 GET 요청 시 HTTP 메서드 = "POST"
Swift 2에서:
extension NSMutableURLRequest {
func setAuthorizationHeader(username username: String, password: String) -> Bool {
guard let data = "\(username):\(password)".dataUsingEncoding(NSUTF8StringEncoding) else { return false }
let base64 = data.base64EncodedStringWithOptions([])
setValue("Basic \(base64)", forHTTPHeaderField: "Authorization")
return true
}
}
SWIFT 3 및 Apache 단순 인증:
func urlSession(_ session: URLSession, task: URLSessionTask,
didReceive challenge: URLAuthenticationChallenge,
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
let credential = URLCredential(user: "test",
password: "test",
persistence: .none)
completionHandler(.useCredential, credential)
}
앱에 구현 중인 일부 자동 전자 메일에 대해 MailGun에 POST를 수행하는 중에도 유사한 문제가 발생했습니다.
저는 큰 HTTP 응답으로 이것을 제대로 작동시킬 수 있었습니다.나는 Keys에 모든 경로를 입력했습니다.내 코드를 github에 업로드하고 인수 중 일부를 변수로 분류하여 나중에 프로그래밍 방식으로 설정할 수 있도록 합니다.
// Email the FBO with desired information
// Parse our Keys.plist so we can use our path
var keys: NSDictionary?
if let path = NSBundle.mainBundle().pathForResource("Keys", ofType: "plist") {
keys = NSDictionary(contentsOfFile: path)
}
if let dict = keys {
// variablize our https path with API key, recipient and message text
let mailgunAPIPath = dict["mailgunAPIPath"] as? String
let emailRecipient = "bar@foo.com"
let emailMessage = "Testing%20email%20sender%20variables"
// Create a session and fill it with our request
let session = NSURLSession.sharedSession()
let request = NSMutableURLRequest(URL: NSURL(string: mailgunAPIPath! + "from=FBOGo%20Reservation%20%3Cscheduler@<my domain>.com%3E&to=reservations@<my domain>.com&to=\(emailRecipient)&subject=A%20New%20Reservation%21&text=\(emailMessage)")!)
// POST and report back with any errors and response codes
request.HTTPMethod = "POST"
let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
if let error = error {
print(error)
}
if let response = response {
print("url = \(response.URL!)")
print("response = \(response)")
let httpResponse = response as! NSHTTPURLResponse
print("response code = \(httpResponse.statusCode)")
}
})
task.resume()
}
메일건 경로가 키에 있습니다.메일건이라는 문자열로서의 플리스트값이 다음과 같은 API 경로:
https://API:key-<my key>@api.mailgun.net/v3/<my domain>.com/messages?
이것이 POST 요청에 타사 코드를 사용하지 않으려는 사람에게 해결책을 제공하기를 바랍니다!
내 솔루션은 다음과 같이 작동합니다.
import UIKit
class LoginViewController: UIViewController, NSURLConnectionDataDelegate {
@IBOutlet var usernameTextField: UITextField
@IBOutlet var passwordTextField: UITextField
@IBAction func login(sender: AnyObject) {
var url = NSURL(string: "YOUR_URL")
var request = NSURLRequest(URL: url)
var connection = NSURLConnection(request: request, delegate: self, startImmediately: true)
}
func connection(connection:NSURLConnection!, willSendRequestForAuthenticationChallenge challenge:NSURLAuthenticationChallenge!) {
if challenge.previousFailureCount > 1 {
} else {
let creds = NSURLCredential(user: usernameTextField.text, password: passwordTextField.text, persistence: NSURLCredentialPersistence.None)
challenge.sender.useCredential(creds, forAuthenticationChallenge: challenge)
}
}
func connection(connection:NSURLConnection!, didReceiveResponse response: NSURLResponse) {
let status = (response as NSHTTPURLResponse).statusCode
println("status code is \(status)")
// 200? Yeah authentication was successful
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
이 클래스를 ViewController의 구현으로 사용할 수 있습니다.필드를 IBOutlet 주석이 달린 변수에 연결하고 Button을 IBAction 주석이 달린 함수에 연결합니다.
설명:함수 로그인에서 NSURL, NSURL 요청 및 NSURL 연결을 사용하여 요청을 생성합니다.여기서 중요한 것은 이 클래스(자체)를 참조하는 딜러입니다.딜러들의 전화를 받으려면 다음과 같이 해야 합니다.
- NSURLConnectionDataDelegate 프로토콜을 클래스에 추가합니다.
- 프로토콜의 기능 "connection:willSendRequestForAuthenticationChallenge" 구현이것은 요청에 자격 증명을 추가하는 데 사용됩니다.
- 프로토콜의 기능 "connection:didReceiveResponse" 구현http 응답 상태 코드를 확인합니다.
로그인 시 json에게 전화합니다 버튼을 클릭
@IBAction func loginClicked(sender : AnyObject){
var request = NSMutableURLRequest(URL: NSURL(string: kLoginURL)) // Here, kLogin contains the Login API.
var session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
var err: NSError?
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(self.criteriaDic(), options: nil, error: &err) // This Line fills the web service with required parameters.
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
// println("Response: \(response)")
var strData = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Body: \(strData)")
var err1: NSError?
var json2 = NSJSONSerialization.JSONObjectWithData(strData.dataUsingEncoding(NSUTF8StringEncoding), options: .MutableLeaves, error:&err1 ) as NSDictionary
println("json2 :\(json2)")
if(err) {
println(err!.localizedDescription)
}
else {
var success = json2["success"] as? Int
println("Succes: \(success)")
}
})
task.resume()
}
여기서 매개변수 사전을 따로 만들었습니다.
var params = ["format":"json", "MobileType":"IOS","MIN":"f8d16d98ad12acdbbe1de647414495ec","UserName":emailTxtField.text,"PWD":passwordTxtField.text,"SigninVia":"SH"]as NSDictionary
return params
}
Swift에 대한 작업 예제UI iOS15 비동기/대기
struct ExampleJSONService {
let passwordString = "user:password"
let configuration = URLSessionConfiguration.default
enum ExampleJSONServiceError: Error {
case failed
case failedToDecode
case invalidStatusCode
}
func fetchStuff(for myID:String) async throws -> [Stuff] {
let passwordData = passwordString.data(using:String.Encoding.utf8)!
let base64EncodedCredential = passwordData.base64EncodedString()
let authString = "Basic \(base64EncodedCredential)"
let session = URLSession(configuration: configuration)
configuration.httpAdditionalHeaders = ["Authorization" : authString]
let dataUrl = "https://toto.org/stuff/\(myID)/data.json"
let url = URL(string: dataUrl)!
var urlRequest = URLRequest(url: url)
urlRequest.setValue("Basic \(base64EncodedCredential)", forHTTPHeaderField: "Authorization")
urlRequest.httpMethod = "GET"
let (data, response) = try await session.data(for: urlRequest)
guard let response = response as? HTTPURLResponse,
response.statusCode == 200 else {
throw PrixJSONServiceError.invalidStatusCode
}
let decodedData = try JSONDecoder().decode([Prix].self, from: data)
return decodedData
}
}
언급URL : https://stackoverflow.com/questions/24379601/how-to-make-an-http-request-basic-auth-in-swift
'source' 카테고리의 다른 글
RC.1에서는 바인딩 구문을 사용하여 일부 스타일을 추가할 수 없습니다. (0) | 2023.09.03 |
---|---|
엔티티 프레임워크 코어를 사용하여 엔티티 모델 암호화 (0) | 2023.08.29 |
각도 5: "컨트롤 컨테이너 공급자 없음" (0) | 2023.08.29 |
여러 행을 하나의 행으로 결합하는 방법 (0) | 2023.08.29 |
Quartz Core, Core Graphics 및 Quartz 2D의 차이점은 무엇입니까? (0) | 2023.08.29 |