Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to provide frontend with JSON web token after server authentication?

Tags:

So far I have only dealt with server-rendered apps, where after a user logs in via username/password or using an OAuth provider (Facebook etc.), the server just sets a session cookie while redirecting to the relevant page.

However now I'm attempting to build an app using a more 'modern' approach, with React on the frontend and a JSON API backend. Apparently the standard choice for this is to use a JSON web token for authentication, however I'm having trouble working out how I'm meant to provide the JWT to the client so it can be stored in session/local storage or wherever.

Example to illustrate better:

  1. User clicks link (/auth/facebook) to log in via Facebook

  2. User is redirected and shown Facebook login form and/or permission dialog (if necessary)

  3. Facebook redirects user back to /auth/facebook/callback with an authorization code in tow, the server exchanges this for an access token and some information about the user

  4. Server finds or creates the user in the DB using the info, then creates a JWT containing a relevant subset of the user data (e.g. ID)

  5. ???

At this point I just want the user to be redirected to the main page for the React app (let's say /app) with the JWT in tow, so the frontend can take over. But I can't think of an (elegant) way to do that without losing the JWT along the way, other than to put it in the query string for the redirect (/app?authtoken=...) - but that will display in the address bar until I remove it manually using replaceState() or whatever, and seems a little weird to me.

Really I'm just wondering how this is typically done, and I'm almost sure I'm missing something here. The server is Node (Koa with Passport), if that helps.

Edit: To be clear, I'm asking what the best way is to provide a token to the client (so it can be saved) after an OAuth redirect flow using Passport.

like image 522
Inkling Avatar asked Feb 02 '17 07:02

Inkling


People also ask

How do I transfer my JWT token to frontend?

In your frontend, store the access token in memory of your client's JavaScript application and store the refresh token in a web store. Send JWT access token as a bearer in HTTP header with each server request that requires authorization. Verify the JWT on your server using the public key (public to your services).

How do you do frontend authentication?

When the frontend needs to authenticate the user, it calls an API endpoint ( /api/login ) on the backend to start the login handshake. The backend uses OpenID connect with Auth0 to authenticate the user and getting the id, access, and refresh tokens. The backend stores the user's tokens in a cache.


2 Answers

I recently ran across this same issue, and, not finding a solution here or elsewhere, wrote this blog post with my in-depth thoughts.

TL;DR: I came up with 3 possible approaches to send the JWT to the client after OAuth logins/redirects:

  1. Save the JWT in a cookie, then extract it on the front-end or server in a future step (eg. extract it on the client with JS, or send a request to the server, server uses the cookie to get the JWT, returns the JWT).
  2. Send the JWT back as part of the query string (which you suggest in your question).
  3. Send back a server-rendered HTML page with a <script> tag that:
    1. Automatically saves the embedded JWT to localStorage
    2. Automatically redirects the client to whatever page you like after that.

(Since logging in with JWTs is essentially equivalent to "saving the JWT to localStorage, my favorite option was #3, but it's possible there are downsides I haven't considered. I'm interested in hearing what others think here.)

Hope that helps!

like image 70
GT2000 Avatar answered Sep 19 '22 05:09

GT2000


  1. Client: Open a popup window via $auth.authenticate('provider name').
  2. Client: Sign in with that provider, if necessary, then authorize the application.
  3. Client: After successful authorization, the popup is redirected back to your app, e.g. http://localhost:3000, with the code (authorization code) query string parameter.
  4. Client: The code parameter is sent back to the parent window that opened the popup.
  5. Client: Parent window closes the popup and sends a POST request to /auth/provider withcode parameter.
  6. Server: Authorization code is exchanged for access token.
  7. Server: User information is retrived using the access token from Step 6.
  8. Server: Look up the user by their unique Provider ID. If user already exists, grab the existing user, otherwise create a new user account.
  9. Server: In both cases of Step 8, create a JSON Web Token and send it back to the client.
  10. Client: Parse the token and save it to Local Storage for subsequent use after page reload.

    Log out

  11. Client: Remove token from Local Storage
like image 24
sabarinathan u Avatar answered Sep 21 '22 05:09

sabarinathan u