I have a React Native app that communicates with a backend API on Azure. This is the setup:
expo-apple-authentication
The Apple sign in code is the same as the example:
const credential = await AppleAuthentication.signInAsync(
{
requestedScopes: [
AppleAuthentication.AppleAuthenticationScope.FULL_NAME,
AppleAuthentication.AppleAuthenticationScope.EMAIL,
],
}
);
And so far that all works, using the provider SDK flow described by the Azure docs:
identityToken
from the credentials{id_token: identityToken}
X-ZUMO-AUTH
header.However, both the identity token and the JWT expire after a day, which means the user needs to log in again. How can I refresh my tokens, without the user having to sign in again?
The Expo docs mention AppleAuthentication.refreshAsync
as a way to refresh the token.
However:
{'_i': 0, '_j': 0, '_k': 0, '_l': 0}
. I can't remember the exact result, but there was zero information.The Azure docs are very brief on refreshing tokens, it simply says "send a GET request to /.auth/refresh". Now, with cookies in a browser that might indeed work, but from an app, we need a bit more. What I tried:
GET https://myapi.azurewebsites.net/.auth/refresh -H "Authorization: Bearer **apple id token**"
, returned 401GET https://myapi.azurewebsites.net/.auth/refresh -H "Authorization: Bearer **Azure JWT**"
, returned 401GET https://myapi.azurewebsites.net/.auth/refresh -H "X-ZUMO-AUTH; **Azure JWT**"
, returned 403POST https://myapi.azurewebsites.net/.auth/refresh -H "Content-Type: application/json" -d '{"id_token": **apple id token**}'
, returned 401For now, I simply require the user to login after a day (after the tokens expired), but I don't like that UX. It feels like this shouldn't be rocket science, and I'm missing something simple. What's a better way? Who managed this, and how?
Okay, I figured it out. Microsoft seems confused, but as per this issue, Azure App Service does not (yet) support storing and managing Apple refresh tokens. You need to implement this on your own. Fortunately, this is straightforward. The process is this:
authorizationCode
.https://appleid.apple.com/auth/token
with the authorization code and your client secret. Apple returns a refresh token and an identity token. Return these to the client app.https://myapi.azurewebsites.net/.auth/login/apple
to get the ZUMO JWT, and provide this JWT in subsequent requests to your server.On refresh:
https://appleid.apple.com/auth/token
with the refresh token and your client secret. Apple returns an identity token. Return this to the client app.https://myapi.azurewebsites.net/.auth/login/apple
to get the ZUMO JWT, and provide this JWT in subsequent requests to your server.This link provides details on how to implement the refresh and refresh token requests.
Note that you do not need a backend endpoint per se, but you have to store your Apple client secret somewhere securely, and this secret needs to be refreshed at least every 6 months.