Search code examples
authenticationnext.jsmobilejwtauthorization

How can I handle seamless authentication from mobile app to web app?


I have a mobile app built with react native, a nestjs API for the mobile app, and I'm working on a web app (nextjs).

The mobile app and API already have JWT based authentication built. I am building the web app from scratch.

At an extremely high level, what I want to do is:

-In my mobile app, the user is already logged in

-The user presses on a button to launch the web app in the browser

-The browser opens the web app, and the user is already logged in. I do not want the user to have to enter credentials at any point.

I'm trying to think of the best strategy for auth in this case. Here is what I've come up with:

1 - App user, already logged in, presses a button to open the web app

2 - App requests a one-time use token from API

3 - On receiving request, API:

3a - Creates a one-time token (OTT). This token is a JWT with an identifier (uuid) in the payload and short expiry time (5m?)

3b - Stores a record in redis, with the identifier as key, an expiry equal to that of the JWT, and a value of the user’s App id

4 - The OTT is sent back to App in the response

5 - App constructs a link to the Store, passing in the OTT in the URL params

6 - The web app is opened in the browser and extracts the OTT from the URL

7 - The web app sends the OTT to API and requests a new token

8 - API verifies the OTT, extracts the identifier, and queries redis for the associated user.

9 - If a record is found, the API extracts the user’s App id from the redis store, immediately deletes the record from redis (ensuring the token can be used only once), and finally uses the extracted id to query the db for the user’s data

10 - API Creates a new JWT with the necessary user data

11 - API sends new JWT back to the web app inside an httponly cookie

12 - The web app receives the cookie and can make requests to the API

This is my first time implementing something like this from scratch, so I am mostly wondering if this is secure. Passing the one time JWT from the mobile app to the web app in query params feels a bit sketchy to me, but because it has a short expiry and would be immediately invalidated, is it relatively secure? Are there considerations I might not be making?

I have not tried to implement this yet, am mostly looking to see if it is a valid approach. I am open to other solutions, but since I am working with an already built token-based auth flow between the mobile app and API, I'm not looking to implement solutions like OAuth at this time.

As always thank you!!


Solution

  • At first sight, the solution sounds reasonable. As you noticed, the critical part is if someone manages to intercept the interim token. They will then be able to get the user's access token and you won't be able to do much about it. Even invalidating the interim token means that you hope that your web app will be the first to use that token, which doesn't have to be the case.

    One thing you could consider is to change the format of the interim token. Because you want to keep its data in the database and make it a single-use token, then you don't need a JWT for that. You can just use a random string that will be the database entry identifier.