OAuth 2.0 with Swift Tutorial
In this OAuth 2.0 Swift tutorial you will learn how to use two different open source libraries to implement OAuth 2.0 in an iOS app. By Owen L Brown.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
OAuth 2.0 with Swift Tutorial
20 mins
- Getting Started
- Explaining the Need for OAuth 2.0
- The Authorization Dance
- Step 0: Registration
- Step 1: Authorization Code
- Step 2: Exchange Code for Token
- Step 3: Get Resources
- Registering With your OAuth 2.0 Provider
- Authenticating with AeroGear and External Browsers
- Configuring the URL Scheme
- Using Embedded Safari View
- OAuthSwift with Embedded Safari View
- Configuring URL Handling
- More About Tokens
- Storing tokens
- Refreshing and Revoking
- Where To Go From Here?
Step 3: Get Resources
Using the access token, Incognito can access protected resources on the server — that is, the resources the end-user granted access to. Your upload is free to proceed.
Ready to see this in action? First, you need to register with the OAuth 2.0 provider: Google.
Registering With your OAuth 2.0 Provider
If you don’t have a Google account, go create one now. It’s OK; I’ll wait for you. :]
Open https://console.developers.google.com/ in your browser; you’ll be prompted to authenticate with Google.
Click Create Project and name your new project Incognito:
Next, you need to enable the Drive API.
Click Library in left menu and search for Google Drive API and select it. On the next screen, click Enable:
Now you need to create new credentials to access your Drive accounts from the app.
Select Credentials in left menu and from the blue Create Credentials drop down, select OAuth client ID.
Then click Configure consent screen and in the screen that appears, fill out the following information:
- Email address: Select your email address
- Product name: Incognito
- Homepage URL: http://www.raywenderlich.com
Click Save and you’ll return to the Client ID screen. Select select iOS and enter com.raywenderlich.Incognito as your Bundle ID.
The authorization server will use the bundle id entered above as the redirect URI.
Finally, click Create. A popup with the Client ID appears, just click Ok.
The important parameter needed for later is the Client ID. You can grab it anytime by clicking Credentials in the left menu and picking your client ID from the OAuth ID list.
Now that you’ve registered with Google, you’re ready to start your OAuth 2.0 implementation using the first OAuth 2.0 library: AeroGear with an external browser.
Authenticating with AeroGear and External Browsers
Open ViewController.swift and add the following imports to the top of the file:
import AeroGearHttp
import AeroGearOAuth2
Now, add the following instance variable inside the ViewController
class:
private let http = Http(baseURL: "https://www.googleapis.com")
You’ll use this instance of Http
, which comes from the AeroGearHttp
library, to perform HTTP requests.
Still in ViewController.swift, find the empty share(_:)
method and add the following code to it:
//1
let googleConfig = GoogleConfig(
clientId: "YOUR_GOOGLE_CLIENT_ID",
scopes:["https://www.googleapis.com/auth/drive"])
//2
let gdModule = AccountManager.addGoogleAccount(config: googleConfig)
//3
http.authzModule = gdModule
//4
let multipartData = MultiPartData(data: snapshot(),
name: "image",
filename: "incognito_photo",
mimeType: "image/jpg")
let multipartArray = ["file": multipartData]
//5
http.request(method: .post, path: "/upload/drive/v2/files", parameters: multipartArray) {
(response, error) in
if (error != nil) {
self.presentAlert("Error", message: error!.localizedDescription)
} else {
self.presentAlert("Success", message: "Successfully uploaded!")
}
}
Here’s what’s going on in the method above:
- Create a configuration. You’ll need to replace
YOUR_GOOGLE_CLIENT_ID
above with the Client ID from your Google Console to use the correct authorization configuration. At initialisation you also define the scope of the grant request. In the case of Incognito, you need access to the Drive API. - You then instantiate an OAuth2 module via
AccountManager
utility methods. - Next you inject the OAuth2 module into the HTTP object, which links the HTTP object to the authorization module.
- Then you create a multi-part data object to encapsulate the information you wish to send to the server.
- Finally, you use a simple HTTP call in to upload the photo. The library checks that an OAuth2 module is plugged into HTTP and makes the appropriate call for you. This will result in one of the following outcomes:
- start the authorization code grant if no access token exists.
- refresh the access token if needed.
- if all tokens are available, simply run the POST call.
Build and run your app; select an image, add an overlay of your choosing, then tap the Share button. Enter your Google credentials if you’re prompted; if you’ve logged in before, your credentials may be cached. You’ll be redirected to the grant page. Tap Accept and…
Boom — you receive the Safari Cannot Open Page error message. :[ What’s up with that?
Once you tap Accept, the Google OAuth site redirects you to com.raywenderlich.Incognito://[some url]. Therefore, you’ll need to enable your app to open this URL scheme.
Note: Safari stores your authentication response in a cookie on the simulator, so you won’t be prompted again to authenticate. To clear these cookies in the simulator, go to Hardware\Erase All Content and Settings.
Note: Safari stores your authentication response in a cookie on the simulator, so you won’t be prompted again to authenticate. To clear these cookies in the simulator, go to Hardware\Erase All Content and Settings.
Configuring the URL Scheme
To allow your user to be re-directed back to Incognito, you’ll needs to associate a custom URL scheme with your app.
Go to the Incognito\Supporting Files group in Xcode and find Info.plist. Right click on it and choose Open As\Source Code.
Add the following to the bottom of the plist, right before the closing </dict> tag:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>com.raywenderlich.Incognito</string>
</array>
</dict>
</array>
The scheme is the first part of a URL. In web pages, for example, the scheme is usually http or https. iOS apps can specify their own custom URL schemes, such as com.raywenderlich.Incognito://doStuff. The important point is to choose a custom scheme that it unique among all apps installed on your users’ devices.
The OAuth 2.0 dance uses your custom URL scheme to re-enter the application from which the request came. Custom schemes, like any URL, can have parameters. In this case, the authorization code is contained in the code
parameter. The OAuth 2.0 library will extract the authorization code from the URL and pass it in the next request in exchange for the access token.
You’ll need to implement a method in Incognito’s AppDelegate
class for the app to respond when it’s launched via a custom URL scheme.
Open AppDelegate.swift and add the following import statement to the top of the file:
import AeroGearOAuth2
Next, implement application(_:open:options)
as shown below:
func application(_ app: UIApplication,
open url: URL,
options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
let notification = Notification(name: Notification.Name(AGAppLaunchedWithURLNotification),
object:nil,
userInfo:[UIApplicationLaunchOptionsKey.url:url])
NotificationCenter.default.post(notification)
return true
}
This method simply creates an Notification
containing the URL used to open the app. The AeroGearOAuth2 library listens for the notification and calls the completionHandler
of the POST
method you invoked above.
Build and run your project again, take a snazzy selfie and dress it up. Click the share button, authenticate yourself, and lo and behold:
You can download the finished Incognito AeroGear project from this section if you wish.
Switching context to an external browser during the OAuth 2.0 authentication step is a bit clunky. There must be a more streamlined approach…