OAuth2 implementation with ORY Hydra, Vapor 3 and iOS 12
Part 4: Set up OAuth2 authorization on iOS with AppAuth
This part of our tutorial series about setting up OAuth2 with ORY Hydra, Vapor and iOS will focus on building the iOS client. It will be a very simple app that only shows a button to create an account and switches to a success message, in case the user successfully logged in. We will use a library called AppAuth to interact with our authorization server.
Part 1: Introduction and setup of ORY Hydra authorization server
Part 2: User management in Vapor backend
Part 3: Set up Vapor backend as identity provider for ORY Hydra
Part 4: Set up OAuth2 authorization on iOS with AppAuth (you are here)
You should checkout the previous parts of the series listed above.
Create iOS Xcode project
Open up Xcode or your editor of choice and create a new Single View application. You will be provided with a
ViewController.swift class already, its view is configured in the storyboard.
Open the storyboard and add a button on the
ViewController that triggers the authentication flow. Then add a hidden label with a success message, that we can show instead after the user logged in successfully.
Next, open the
ViewController.swift file and drag outlets for the two buttons in there and also one for the button action. Call that function
Now we got the basic setup of the iOS project. Next we want to integrate a 3rd party library called AppAuth that will take care of interacting with the authorization server.
Interaction with the authorization server via AppAuth
After adding AppAuth to our project, we want to have a dedicated service that is taking care of everything related to authentication. Create a new file called
AuthService.swift and import
AppAuth as a dependency.
Create authorization request
To authorize a user using
AppAuth we’ll need to create an
OIDAuthorizationRequest. Create a function in the
authorize and create an authorization request in there:
The authorization request takes quite a few parameters:
configuration: The configuration is needed to construct an
OIDAuthorizationService. It contains the URLs for accessing the Hydra authorization server.
clientId: The identifier of the client we registered on our Hydra server.
clientSecret: The secret of the client we registered on our Hydra server (in production you should definitely not store this information on the iOS client).
scopes: The scope describes what kind of information we want to access, similar to the
requested_scopeparameter in the consent request of the identity provider. In our case we want to make an OpenID connect request and want to be able to receive refresh tokens (this is what
offlineis used for).
redirectURL: The redirect URL that should be called after a successful login.
responseType: The response type of the authorization request, could be e.g.
token. As we are using the authorization code flow, we want to use
additionalParameters: Any additional parameters needed for authorization. None needed in our case.
Define authorization URLs
So, there is some information we need to pass to AppAuth to enable it to request authorization from our Hydra server. Add the following properties at the top of our
tokenEndpoint: URLs of Hydra’s Public API
redirectURL: can be chosen by us, but needs to follow a certain URL scheme to be able to be detected by the app
clientSecret: identifier and secret of the client we registered on our Hydra server
config: service configuration for AppAuth containing the
To enable the iOS app to handle the
redirectURL we need to add the URL scheme in the
Info.plist. Open it and add a new entry called
URL types like this:
In addition we need to allow the app to handle non-SSL URLs. For that we need to add another entry to the
App Transport Security Settings:
Trigger authorization request
After creating the authorization request, we now need to actually trigger that request. We can use a convenience function provided by
AppAuth that creates a new
OIDExternalUserAgentSession, which we’ll need to hold in our
AuthService. Add this line at the top of our
authorize to look like this:
First we changed the signature of the function to take in a UIViewController and callbacks for the success and error cases. Then we trigger the authorization request by creating a new authorization session using the request we created before.
After creating the authorization session we’ll receive either an
OIDAuthState object or an error.
OIDAuthState is a convenience class by
AppAuth that contains all relevant information about the authorization state of the user.
Go back to the
ViewController and call this function when the create account button is tapped.
We created an instance of
AuthService and call
authorize on button tap. If we can successfully authorize the user, we show the success message instead of the button.
That’s it for the iOS part.
Testing our setup
We now developed all three parts we need for implementing an OAuth2 authorization. To be able to test it, we need to start our Hydra server, run our backend and run the iOS client.
- Start Hydra Server: Revisit Part 1 and follow the steps to start the Hydra server and create the client
- Run Backend in Xcode: Just start the Run configuration of our Vapor backend in Xcode
- Run iOS Client in Xcode: Also here, just run the default scheme in Xcode
In your iOS simulator you should now see a white screen with the Create Account button. If you tap it, you should be redirected to a web browser that is displaying the Login UI. Try registering a user and see the success message afterwards. You can checkout the short video in the beginning of Part 1 to see the expected result.
Congrats! You’ve made it all the way and implemented your own authorization code flow with ORY Hydra, Vapor and iOS.
We plan on writing follow-up parts for this tutorial about authorization of users using ORY Oathkeeper and making the whole setup production ready.
If you have problems with the tutorial or comments, feel free to contact us via our website!
OAuth2 for mobile
You can find the fully implemented iOS app for this tutorial on Github!