在 iOS 上使用 OAuth2 进行身份验证 [英] Authenticating with OAuth2 on iOS
问题描述
我目前正在尝试使用 OAuth2 授权我的用户.我目前正在使用以下库:https://github.com/p2/OAuth2
I am currently trying to authorize my users with OAuth2. I am currently using the following library: 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()
当我运行它时,它会在浏览器中加载 google 并且我能够登录.然后它会询问我在范围中声明的权限,并且工作正常.我点击确定打开,它会将我重定向回我的应用.
When I run this it loads up google in the browser and I am able to sign in. It then asks me about the permissions I have declared in the scope and that works fine. I click ok open and it redirects me back to my app.
但是,当我再次运行此代码时,我期望访问令牌已存储在钥匙串中.但是,这似乎不起作用.
However when I run this code again I am expecting that the access token has been stored in the key chain. However this doesn't seem to be working.
我查看了源代码并发现了以下检查:tryToObtainAccessTokenIfNeeded
总是返回 false.这意味着我再次获得需要点击允许"的页面.
I have looked inside the source code and found the following check: tryToObtainAccessTokenIfNeeded
which always returns false. This means I get the page again where I need to click 'Allow'.
我想知道是否有人能帮我弄清楚为什么它没有在钥匙串中保存任何东西.这是否也意味着用户并未真正通过身份验证?
I was wondering if someone could help me figure out why it's not saving anything in the keychain. Also does this mean the user is not really being authenticated?
谢谢.
===
编辑
根据 Pascal 的评论添加了 oauth2.verbose = true
.我得到以下输出.
Have added oauth2.verbose = true
as per Pascal's comment. I get the following output.
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
这就是我认为正在发生的事情.但是我仍然不确定为什么它没有在钥匙串中保存/找到任何东西.
Which is what I thought was happening. However I am still unsure as to why it's not saving / finding anything in the keychain.
======
编辑 2
事实证明,我实际上根本没有取回访问令牌.请参阅此对话:https://github.com/p2/OAuth2/issues/109 以及我在下面的回答.
It turns out that I wasn't actually getting an access token back at all. Please see this conversation: https://github.com/p2/OAuth2/issues/109 and my answer below.
推荐答案
在 Pascal 的帮助下:https://github.com/p2/OAuth2/issues/109 我已经设法让它工作.事实证明,我没有执行 step: '3 Authorize the User' 正如我应该做的那样.
With the help from Pascal here: https://github.com/p2/OAuth2/issues/109 I have managed to get it working. Turns out that I wasn't implementing step: '3 Authorize the User' as I should have been.
所以一个完整的解决方案是:
So a complete solution is:
在我的视图控制器中,我有以下内容:
Inside my view controller I have the following:
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)
}
上面的代码应该处理将您发送到您可以登录的谷歌网页,然后点击允许.
The above code should handle sending you to the google web page where you can log in and then click allow.
现在您需要在应用程序委托中处理返回应用程序:
Now you need to handle returning to the app in the 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
}
希望这能帮助其他在尝试获取访问令牌时遇到问题的人.
Hopefully this will help anyone else who might be having issues trying to get an access token.
这篇关于在 iOS 上使用 OAuth2 进行身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!