1️⃣ TargetApp - Info - URL Scheme(Authorization callback URL) 설정하기
2️⃣ UIApplication.shared.open(url:)으로 url 열기
let clientID = "a1b2c3d4"
let scope = "repo gist user"
let urlString = "https://github.com/login/oauth/authorize"
var components = URLComponents(string: urlString)!
components.queryItems = [URLQueryItem(name: "client_id", value: self.clientID),
URLQueryItem(name: "scope", value: self.scope)]
UIApplication.shared.open(url)
3️⃣ login 성공 후 redirect, Github으로 부터 리턴받은 code를 가지고 access token 얻기
// SceneDelegate.swift
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
if let url = URLContexts.first?.url {
print(url)
let code = url.absoluteString.components(separatedBy: "code=").last ?? ""
print(code)
requestAccessToken(with: code)
}
}
func requestAccessToken(with code: String) {
let url = "https://github.com/login/oauth/access_token"
let parameters = ["client_id": APIRequestManager.clientID,
"client_secret": APIRequestManager.clientSecret,
"code": code]
var request = URLRequest(url: URL(string: url)!)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
guard let bodyData = try? JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted) else { return }
request.httpBody = bodyData
URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in
guard let data = data else { return }
guard let json = try? JSONSerialization.jsonObject(with: data, options: []) else { return }
print(json)
if let data = json as? [String: Any] {
// handle data
}
}).resume()
}
ASWebAuthenticationSession
객체 생성하기ASWebAuthenticationPresentationContextProviding
프로토콜 채택해서 presentationAnchor
함수 구현하기class LoginViewController: UIViewController {
var authenticationSession: ASWebAuthenticationSession?
let authURL = URL(string: "https://github.com/login/oauth/authorize?client_id=\(APIRequestManager.clientID)")
let callbackUrlScheme = "baseballapp"
override func viewDidLoad() {
super.viewDidLoad()
}
private func auth() {
authenticationSession = ASWebAuthenticationSession.init(url: authURL!, callbackURLScheme: callbackUrlScheme, completionHandler: { (callbackURL:URL?, error:Error?) in
print(callbackURL)
guard error == nil,
let callbackURL = callbackURL,
let queryItems = URLComponents(string: callbackURL.absoluteString)?.queryItems,
let code = queryItems.first(where: { $0.name == "code" })?.value else {
print("An error occurred when attempting to sign in.")
return
}
self.requestAccessToken(with: code)
})
authenticationSession?.presentationContextProvider = self
authenticationSession?.start()
}
func requestAccessToken(with code: String) {
let url = "https://github.com/login/oauth/access_token"
let parameters = ["client_id": APIRequestManager.clientID,
"client_secret": APIRequestManager.clientSecret,
"code": code]
var request = URLRequest(url: URL(string: url)!)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
guard let bodyData = try? JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted) else { return }
request.httpBody = bodyData
URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in
guard let data = data else { return }
guard let json = try? JSONSerialization.jsonObject(with: data, options: []) else { return }
print(json)
if let data = json as? [String: Any] {
// handle data
}
}).resume()
}
@IBAction func login() {
auth()
}
}
extension LoginViewController: ASWebAuthenticationPresentationContextProviding {
func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
return self.view.window ?? ASPresentationAnchor()
}
}
https://d2.naver.com/helloworld/24942
https://medium.com/@jungkim/앱에서-oauth2-연동하기-dadcce91e921
https://www.raywenderlich.com/19364429-implementing-oauth-with-aswebauthenticationsession
https://zeddios.tistory.com/1102
and... https://deptno.github.io/posts/2018/Github-OAuth-404/
잘 보고 갑니다 :)