Dealing with OAuth2.0 in iOS apps (swift)

Saleh Masum
5 min readAug 28, 2022

--

OAuth is an authorization protocol that lets you approve one application interacting with another on your behalf without giving away user credentials, like your username and password.Instead of storing usernames and passwords in our app, we’ll be using an access token that we obtain via OAuth to send authorized requests to the server and retrieve data.

The five basic steps of the OAuth flow:

  1. Client requests authorization to access data from Spotify
  2. Spotify authorizes access to client
  3. User grants app access their Spotify data
  4. Client receives access token from Spotify
  5. Client uses access token to request data from Spotify

In this article I will describe required steps to communicate with a OAuth2 compliant server, in this case Spotify. Almost same approach is followed elsewhere for example Google, Facebook etc. This is not going be a detail tutorial, I will only highlight the overview, for complete source code please check out the GitHub repo. Once you go through this, I hope you will get a clear picture about it.

Step 1 : The first thing you need to do is making an api call for an authorisation code following documentation of your server of choice. As I was trying to communicate with Spotify server for me the end point I got is this :

You also need to provide additional information through query parameters. For example response_type, client_id, redirect_uri, scopes etc. Once you append everything the complete url would look something like this:

You might ask, how do you get client_id, scopes etc. You get these informations from developer Dashboard(devloper.spotify.com). Same rule applies to google or facebook or any compliant server of your choice.

Step 2: Open the url that we found in step 1 in a web view. So if some one press the button “Sign In with Spotify”, we open the url in a web view in a seperate screen like this:

Upon successful login, it will ask your authorization for what kind of data / information client app will be able to access. If you agree with this then it will get you to redirect_uri page (any page that you provide in dashboard)that we provided along with the authorisation url. Here is the total web view code:

Here we are doing two important things, number one is in web view delegate method ‘webView didStartProvisionalNavigation’ we are getting the code from server. Number two is we are making an api call with this code for an accessToken as you see in the function ‘initiateRequestForAccessToken’. The deal is we are asking server to simply give us an accessToken in exchange of this code so that we can make necessary api call for required resources.

Step 3: Once you get accessToken from server you can make any api call that you are authorised to in step1. Let’s go ahead and see the detail source code of how we can make this call happen.

As you can see the function ‘exchangeCodeForToken’ is pretty straightforward and self explanatory. We are putting together clientID & clientSecret, convert it to base64EncodedString and send it as ‘Authorization’ header, along with ‘grant-type’, ‘code’ & ‘redirect_uri’ as http body. If the request is successful here’s what we get as response:

Now with this access_token you can make any api call to server. We are storing tokens as well as Token expiry date in UserDefaults for simplicity sake but please use keychain for security reason which is highly recommended.

Step 4: Here we will discuss how will you refresh your access_token when it will get expired. As I was playing around with Spotify api, they provide 1 hour(3600sec) duration for the access_token to live. After this period any subsequent request will be refused by server. So here’s what we will to do in order to get a new token.

Each time a new api call arrives to our network layer we will check if the request is already got expired or it is still alive and valid. If access token is valid we will use it, if not then we will make another api call to the same end point ‘/api/token’ for a new access_token. This time grant_type would be refresh_token and we will also provide refresh token as request body. Everything would be same like before including Content-Type & Authorization header. If the call is successful you will get a new access_token with the same validity. Use it for your next subsequent calls.

Repeat this strategy for refreshing access_token for every possible call you ever make. The code for this would look something like this:

It is just a very simple request almost same like before only difference is that I am checking the validity of the access token by the function ‘isAccessTokenExpired’. Here for the safety sake I am adding five minutes to current date as buffer time. That means if some one request second api, 55 minutes(considering token validity is 1 hour) after getting access_token for the first time, he/she would still need to refresh his/her token (by making the api call ‘withValidToken’ which will eventually call ‘refreshIfNeeded’).

Step 5: There’s another little thing going on here. The question is if token is expired and ten different request needs a new access_token almost at the same time. How do you deal with this scenario? Would you let all of them go through? It will work but it will cost you additional resources(depending on your server response time the number may vary).

Here’s how we can optimize the experience. We just let the first api call go through and put all the remaining requests into a queue. When we get new access_token from our first request’s response we will serve all the remaining requests from queue with the same access token. This way we are making sure we are only allowing a single request to go through at any given time.

Here’s how the code would look like:

This way you will never run out of valid token and achieve a seamless and solid experience throughout your application. Please go ahead and check out the complete project source code.

--

--