使用iOS上的OAuth2进行身份验证

时间:2016-05-12 13:06:22

标签: ios swift keychain google-oauth2 oauth2

我目前正在尝试使用OAuth2授权我的用户。我目前正在使用以下库:https://github.com/p2/OAuth2

let oauth2 = OAuth2CodeGrant(settings: [
        "client_id": "my-id",
        "authorize_uri": "https://accounts.google.com/o/oauth2/auth",
        "token_uri": "https://www.googleapis.com/oauth2/v3/token",
        "scope": "profile",     // depends on the API you use
        "redirect_uris": ["com.TestAuthorizeApp:/oauth2Callback"],
        ])

    //let oauth2 = OAuth2CodeGrant(settings: settings)
    oauth2.onAuthorize = { parameters in
        print("Did authorize with parameters: \(parameters)")
    }
    oauth2.onFailure = { error in        // `error` is nil on cancel
        if let error = error {
            print("Authorization went wrong: \(error)")
        }
    }

    oauth2.authConfig.authorizeEmbedded = false
    oauth2.authorize()

当我运行它时,它会在浏览器中加载谷歌并且我能够登录。然后它会询问我在范围内声明的权限,并且工作正常。我点击确定打开,它将我重定向回我的应用程序。

然而,当我再次运行此代码时,我希望访问令牌已存储在密钥链中。然而,这似乎并没有起作用。

我查看了源代码并找到了以下检查:tryToObtainAccessTokenIfNeeded总是返回false。这意味着我再次获取页面,我需要点击“允许”#。

我想知道是否有人可以帮我弄清楚为什么它不会在钥匙串中保存任何东西。这是否意味着用户并未真正进行身份验证?

感谢。

===

修改

根据Pascal的评论添加了oauth2.verbose = true。我得到以下输出。

 OAuth2: Looking for items in keychain
 OAuth2: No access token, maybe I can refresh
 OAuth2: I don't have a refresh token, not trying to refresh

我认为这是在发生什么。但是我仍然不确定它为什么不在钥匙串中保存/找到任何东西。

=====

修改2

事实证明,我实际上并没有获得访问令牌。请参阅此对话:https://github.com/p2/OAuth2/issues/109以及我在下面的回答。

1 个答案:

答案 0 :(得分:5)

在Pascal的帮助下:https://github.com/p2/OAuth2/issues/109我设法让它运转起来。事实证明,我没有实施步骤:' 3授权用户'我本来应该的。

完整的解决方案是:

在我的视图控制器中,我有以下内容:

let OAuth2AppDidReceiveCallbackNotification = "OAuth2AppDidReceiveCallback"

override func viewDidLoad() {
    super.viewDidLoad()

    // This notification is for handling step 3 in guide.
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ViewController.handleRedirect(_:)), name: OAuth2AppDidReceiveCallbackNotification, object: nil)
}

func authoriseUser {
    let oauth2 = OAuth2CodeGrant(settings: [
        "client_id": "my-id", // Use own client_id here
        "authorize_uri": "https://accounts.google.com/o/oauth2/auth",
        "token_uri": "https://www.googleapis.com/oauth2/v3/token",
        "scope": "profile",     // depends on the API you use
        "redirect_uris": ["com.TestAuthorizeApp:/oauth2Callback"],
        ])

     //let oauth2 = OAuth2CodeGrant(settings: settings)
     oauth2.onAuthorize = { parameters in
        print("Did authorize with parameters: \(parameters)")
     }
     oauth2.onFailure = { error in        // `error` is nil on cancel
         if let error = error {
             print("Authorization went wrong: \(error)")
         }
     }

     oauth2.authConfig.authorizeEmbedded = false
     oauth2.authorize()
 }

// This method gets called by notification and is the last thing we need to do to get our access token. 
func handleRedirect(notification: NSNotification) {
    oauth2.handleRedirectURL(notification.object as! NSURL)
}

以上代码应处理将您发送到您可以登录的Google网页,然后点击允许。

现在您需要处理在app delegate中返回应用程序:

 let OAuth2AppDidReceiveCallbackNotification = "OAuth2AppDidReceiveCallback"

 func application(application: UIApplication,
                 openURL url: NSURL,
                         sourceApplication: String?,
                         annotation: AnyObject) -> Bool {
    // you should probably first check if this is your URL being opened
    NSNotificationCenter.defaultCenter().postNotificationName(OAuth2AppDidReceiveCallbackNotification, object: url)

    return true
}

希望这可以帮助其他可能在尝试获取访问令牌时遇到问题的人。