프로그래밍/iOS

Github OAuth로 로그인하기

병인 2020. 12. 20. 17:09

0. Github Developer 에서 앱 설정

1. LoginManager 만들기

class LoginManager {

    static let shared = LoginManager()

    private init() {}

    private let client_id = "클라이언트 아이디를 넣어준다."
    private let client_secret = "클라이언트 Secret을 넣어준다."

    func requestCodeToGitHub() {
        let scope = "repo,user"
        let urlString = "https://github.com/login/oauth/authorize?client_id=\(client_id)&scope=\(scope)"
        if let url = URL(string: urlString), UIApplication.shared.canOpenURL(url) {
            UIApplication.shared.open(url)
            // redirect to scene(_:openURLContexts:) if user authorized
        }
    }

    func requestAccessTokenToGithub(with code: String) {
        guard let url = URL(string: "https://github.com/login/oauth/access_token") else {return}
        let session = URLSession.shared
        let parameters = ["client_id": client_id,
                          "client_secret": client_secret,
                          "code": code]
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        do {
            request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
        } catch let error {
            print(error.localizedDescription)
        }
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("application/json", forHTTPHeaderField: "Accept")
        let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
            guard error == nil else {
                return
            }
            guard let data = data else {
                return
            }
            guard let json = try! JSONSerialization.jsonObject(with: data) as? [String: Any] else {
                            print(String(data: data, encoding: .utf8) ?? "Not string?!?")
                            return
                        }
            // json["access_token"] access_token 값
            self.getUser(accessToken: json["access_token"] as! String)
        })
        task.resume()
    }
    func getUser(accessToken: String) {
        guard let url = URL(string: "https://api.github.com/user") else {return}
        let session = URLSession.shared
        var request = URLRequest(url: url)
        request.httpMethod = "GET"
        request.addValue("token \(accessToken)", forHTTPHeaderField: "Authorization")
        request.addValue("application/vnd.github.v3+json", forHTTPHeaderField: "Accept")
        let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
            guard error == nil else {
                return
            }
            guard let data = data else {
                return
            }
            guard let json = try! JSONSerialization.jsonObject(with: data) as? [String: Any] else {
                            print(String(data: data, encoding: .utf8) ?? "Not string?!?")
                            return
                        }
            // 프로필 사진 주소
            print(json["avatar_url"] as! String)
            // 이름 가져오기
            print(json["name"] as! String)
        })
        task.resume()
    }
}
  • 프로젝트에서 필요한 프로필 사진 주소 와 이름 만 가져왔다. 이 부분은 JSON을 분석 한 후, 자신에 맞는 정보를 가져오면 된다.

2. Button Action에 연결하기

@IBAction func githubLoginButtonTouch(_ sender: UIButton) {
        LoginManager.shared.requestCodeToGitHub()
    }
  • 따로 로그인 버튼을 제작하고 해당 버튼의 터치 이벤트 때, RequestCodeToGitHub 함수를 호출한다.

3. App / Scene Delegate에 함수 추가하기(선택사항)

  • 일반적으로는 Github는 로그인 성공시 AccessToken 값 및 기타 JSON 값을 서버에 보내준다.

  • 참고자료 사이트에 보면 따로 설정을 할 경우 클라이언트로 반환할 수 있다.

 func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
        if let url = URLContexts.first?.url {
            if url.absoluteString.starts(with: "githubprviewer://") {
                if let code = url.absoluteString.split(separator: "=").last.map({ String($0) }) {
                    LoginManager.shared.requestAccessTokenToGithub(with: code)
                }
            }
        }
    }
  • 자신이 쓰는 SceneDelegate 혹은 AppDelegate에 해당 코드를 작성하면 된다.

  • 문제가 안된다면 서버에 따로 Json을 받을 수 있게 Get API를 만드는 것이 가장 좋다.

정리

  • 버튼 터치 -> LoginManager의 requestCodeToGitHub 함수 호출 -> 깃허브에 로그인 후 반환되는 값을 서버에 전달 후 처리

  • 클라이언트에서 해결 할 경우 Scene 함수에서 requestAccessTokenToGithub 호출

[참고 자료]

 

[iOS] Github OAuth Access Token 얻기 (깃헙으로 로그인)

Authorizing OAuth Apps 문서를 보고 따라한 기록-!! 저는 Github API를 이용해서 private repo에 접근하려고 (풀리퀘 등등 얻어오기 위함) Github OAuth Access Token이 필요해서 따라하게 되었습니다 :-) [..

eunjin3786.tistory.com