Implement OAuth2 PKCE in Swift

Marco Eidinger
Geek Culture
Published in
5 min readDec 18, 2021

I’ll teach and share an OAuth2 PKCE implementation written in Swift in this blog post. This implementation is testable with an iOS app leveraging the free service of Auth0. I’ll explain how to sign-up for your very own account and to modify the test application to use your account.

Note: I wrote this blog post for research purposes. I encourage you to use existing SDKs based on the service you are using.

PKCE

The OAuth framework specifies several grant types for different use cases. The commonly known ones are

  • Authorization Code: used by confidential and public clients to exchange an authorization code for an access token.
  • Client Credentials: used by clients to obtain an access token outside of the context of

But there are many more, including Proof Key for Code Exchange by OAuth Public Clients.

PKCE (RFC 7636) is an extension to the Authorization Code flow to prevent Cross-Site Request Forgery (CSRF) and authorization code injection attacks.

The technique involves the client first creating a secret and then using that secret again when exchanging the authorization code for an access token. If the code gets intercepted, it will not be useful since the token request relies on the initial secret.

A great way to get more familiar with the involved steps is to use the PKCE Example on the OAuth 2.0 Playground.

Here is a sequence diagram published by Auth0 for visual explanation.

Auth0 also created a helpful guide on building your own solution as part of the Add Login Using the Authorization Code Flow with PKCE guide.

Swift Implementation

I will implement all necessary steps in a class.

Encapsulate OAuth 2.0 PKCE client handling in a single class

All parameters needed will be passed into to the class as a struct.

Encapsulate parameters in a struct

The function shall asynchronously return either the access token response from the authorization server or an error.

Return types

To redirect the user to the authorization server along with the code_challenge.I'll use the ASWebAuthenticationSession from Apple's AuthenticationServices.

The complete implementation can be found here.

iOS Test App

I created an iOS test application to verify the PKCE implementation. To start the flow, the user will touch a button. The following code will then be executed.

The complete code for the test app can be in one of my GitHub repositories.

The authorization server used for testing by the app is from Auth0. I’ll explain how to create an own account in the next chapter. No worries, it is straightforward, and it’s free.

Test Environment with Auth0

Sign-up for Auth0 (free starter plan) is quick and easy by using your existing GitHub account

Sign Up for Auth0 account. It’s free

You then can choose a region and create your Auth0 account.

Choose a region for your tenant
Let’s get started in Auth0 cockpit

Let’s create a user for testing.

You don’t have any users yet
Create the first user

Let’s create a new native application.

A default app exist but we want our own!
Create a native application
The app with its domain and client id

You will need to use the Domain and the Client ID later in Swift.

You have to specify the allowed Callback and Logout URLs based on the iOS app bundle identifier (the test app is using us.eidinger.AppUsingPKCE).

Add Allowed Callback URLs

Let’s double-check that Authorization Code Grant is set (it should be as that's the default) and save the changes.

Authorization Code needs to be selected

Running Test App

Using the client id, domain we can instrument the demo app

Replace values with your own account / app information

and run it on the iOS simulator.

Touch “Sign In” to start the flow

Touching the Sing In button will trigger ASWebAuthenticationSession to redirect the user to the authorization server.

User gets redirected. So far so good

Let’s use the credentials of the user created in Auth0.

Do you remember the password you set for the user you created earlier?

Touching the Continue button will return the control back to the test app. The flow will continue (i.e. get access token with the code received from authorization server and the code_verifier and finally display the received access token.

Yeah, it works :)

I hope this guide was helpful to get you familiar with PKCE and to give you an idea how you would implement it on the client with Swift.

Originally published at https://blog.eidinger.info.

--

--

Marco Eidinger
Geek Culture

Software Engineer open-source and enterprise mobile SDKs for iOS and macOS developers | @MarcoEidinger on Twitter | visit blog.eidinger.info