Проверка подлинности OAuth с использованием GitHub в приложениях iOS - как это работает - PullRequest
0 голосов
/ 21 сентября 2018

Я пытаюсь понять, как работает аутентификация oauth с GITHUB в случае приложений IOS.

Я занимаюсь разработкой приложения IOS и хочу использовать GITHUB для аутентификации при входе.

Вот поток моего приложения.

  1. Регистрация пользователя - это автономный процесс, который происходит вне моего приложения.Когда я создаю учетную запись для пользователя, я прошу его указать адрес электронной почты GITHUB.Я сохраняю этот адрес электронной почты в нашей БД как ИД пользователя для этого пользователя.

  2. Получить токен доступа из GITHUB - когда пользователь открывает наше приложение, мы направляем его на https://github.com/login/oauth/authorize с помощью веб-просмотра.После успешного входа пользователя в учетную запись GITHUB я использую https://github.com/login/oauth/access_token для получения токена доступа.

  3. Получение адреса электронной почты с использованием токена доступа - я использую https://api.github.com/user/emails для полученияадрес электронной почты зарегистрированной учетной записи с использованием токена доступа, который я получил на шаге 2.

  4. Проверка адреса электронной почты: я проверяю адрес электронной почты, полученный на шаге 3, для своей базы данных.Если идентификатор пользователя существует, то пользователь сможет выполнять транзакции в нашем приложении.

Сразу после того, как контроль проверки GITHUB возвращается к контроллеру просмотра, у которого есть веб-просмотр для GITHUB, и появляется пустой экран.Как мне перенести поток на следующий viewcontroller?

Вот мой код ViewController:

import UIKit
import WebKit

class Login: UIViewController, UIWebViewDelegate {

    @IBOutlet weak var webview: UIWebView!
    override func viewDidLoad() {
        super.viewDidLoad()

        let authURL = String(format: "%@?client_id=%@&redirect_uri=%@&scope=%@", arguments: [GITHUB.GITHUB_AUTHURL,GITHUB.GITHUB_CLIENT_ID,GITHUB.GITHUB_REDIRECT_URI,GITHUB.GITHUB_SCOPE])

        let urlRequest = URLRequest.init(url: URL.init(string: authURL)!)
        webview.loadRequest(urlRequest)
        webview.delegate = self
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func webView(_ webview: UIWebView, shouldStartLoadWith request:URLRequest, navigationType: UIWebViewNavigationType) -> Bool{
        return checkRequestForCallbackURL(request: request)
    }

    func checkRequestForCallbackURL(request: URLRequest) -> Bool {
        //print("3. IN FUNCTION checkRequestForCallbackURL")

        let requestURLString = (request.url?.absoluteString)! as String
        //print("3. requestURLString=\(requestURLString)")

        if requestURLString.hasPrefix(GITHUB.GITHUB_REDIRECT_URI) {

            let range: Range<String.Index> = requestURLString.range(of: "?code=")!

            handleGithubCode(code: requestURLString.substring(from: range.upperBound))

            return false;
        }

        return true
    }

    func handleGithubCode(code: String) {

            let urlString = "https://github.com/login/oauth/access_token"
            if let tokenUrl = URL(string: urlString) {

                let req = NSMutableURLRequest(url: tokenUrl)
                req.httpMethod = "POST"
                req.addValue("application/json", forHTTPHeaderField: "Content-Type")
                req.addValue("application/json", forHTTPHeaderField: "Accept")

                let params = [
                    "client_id" : GITHUB.GITHUB_CLIENT_ID,
                    "client_secret" : GITHUB.GITHUB_CLIENTSECRET,
                    "code" : code
                ]

                req.httpBody = try? JSONSerialization.data(withJSONObject: params, options: [])
                let task = URLSession.shared.dataTask(with: req as URLRequest) { data, response, error in

                    if let data = data {
                        do {
                            if let content = try JSONSerialization.jsonObject(with: data, options: []) as? [String: AnyObject] {
                                if let accessToken = content["access_token"] as? String {
                                    self.getComposerToken(accessToken: accessToken)

                                }
                            }
                        } catch {}
                    }
                }
                task.resume()
            }
    }

    func getComposerToken(accessToken: String) {
        print("5. accessToken=\(accessToken)")

        let def = "NO_DATA"

        let composerUrl = "http://192.168.100.112/kubher/getAccessToken.php?token=\(accessToken)"
        guard let url = URL(string: composerUrl) else { return }

        URLSession.shared.dataTask(with: url) { (data, response, error) in
            if let response = response {
                //print(response)
            }

            if let data = data {
                do {
                    let json = try? JSONSerialization.jsonObject(with: data, options: [])

                    if let dict = json as? [String: Any],
                        let token = dict["accessToken"] {
                        print("Blockchain Token:\(token)")
                    }
                } catch {
                    print(error)
                }
            }
        }.resume()
  }
}

1 Ответ

0 голосов
/ 23 сентября 2018

Переход к следующему viewcontroller зависит от архитектуры вашего кода.Попробуйте следующий код в зависимости от вашего дизайна.Вариант 1: Если вам нужно вернуться к предыдущему ViewController, просто измените вашу getComposerToken функцию:

if let dict = json as? [String: Any], {
    let token = dict["accessToken"] {
    print("Blockchain Token:\(token)")
    dispatch_async(dispatch_get_main_queue()) {
        self.presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
    }
    }
}

opt 2: С другой стороны, если вы используете Segue для следующего viewController в stoaryboard, дайте вашему segue имя (идентификатор), а затем следуйте этому коду:

if let dict = json as? [String: Any], {
        let token = dict["accessToken"] {
        print("Blockchain Token:\(token)")
        dispatch_async(dispatch_get_main_queue()) {
            self.performSegue(withIdentifier: "YourSegueName", sender: token)
        }
      }
    }

Кроме того, вы должны переопределить метод подготовки для передачи данных

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "segueName" {
            let viewController = segue.destination as? YourViewController
            if let token = sender as? String {
                viewController?.token = token
            }
        }
    }
}

OPT 3: Если вы используете контроллер push-представления после создания из раскадровки, вы должны дать своему контроллеру представления идентификатор в раскадровке, а затем вы можете создать его экземпляр с помощью и нажать его с помощью:

if let dict = json as? [String: Any], {
    let token = dict["accessToken"] {
    let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
    let abcViewController = storyboard.instantiateViewControllerWithIdentifier("YourControlleridentifier") as! YourViewController
YourViewController.token = token
navigationController?.pushViewController(YourViewController, animated: true)
}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...