Search code examples
reactjsexpressauthenticationrelayjspassport.js

Authentication strategy for Express server, ReactJS and Relay application using Passport


After some weeks building my ReactJS application, it's time to add authentication to it. This is very confusing to me.

My application is composed of:

  • A Express server that runs a GraphQL Server over mongoose/MongoDB on port 3001.
  • A client ReactJS + Relay application with React Router V4, running on port 3000.

I have a script that starts concurrently both the server and client (npm start) and that makes it all works fine. The server is loaded, the client is loaded, the browser opens on port 3000 and requests GraphQL data using RelayJs on server on port 3001. All fine.

I´ve used Passport authentication in the past using LocalStrategy. Passport goes to the database, checks username and password and let the request proceeed using the router in the express middleware. Works fine, but - on the server side - not on the client side.

My goal is to make the user launch the client application (today pointing the browser to port 3000) and them:

  • If not authorized, it will be redirected to a login page.

  • If authenticated, the user will be redirected to the application.

  • Using 'remember me' the user may come back to app without logging in (in the same browser for some time - whole day).

  • If user does not remember username/password, asks for resetting and new credentials will be send through e-mail.

For now I cannot see how these things will work together. Passport runs on the server, and all that logic is done in the client (except for gathering user info on MongoDB).

I can see two approaches:

a) Building a proxy server that will exclusively handle authentication on port 3000. If authenticated, it will proxy to real ReactJS application, that will be running on another internal port. But doing so, I cannot find out how the user will get the app for logging in when first hitting port 3000. To do so I will also have to change my client, as it is a create-react-app ejected with webpack-dev-server embedded (in fact after ejecting I can't understand very much what is going inside client scripts). In short - confusing and need to change my architecture.

b) Add Passport to my ReactJS application. This won't work as password is build to run on node (server side). I can't find out if this is even possible or how to do it.

After these "not clear and confusing" architectures, I can´t find out what to do.


Solution

  • You can do it like this:

    • Create route in express for login
    • Use passport middleware on that route
    • Create login form in React
    • Send form credentials data via POST to that express login route
    • After passport has verified that username and password are alright, it sends you back that all is ok and you can send user to your App.

    What express will send you depends on what you want to use on client. It can be cookie, token (JWT)...

    That way you are handling Auth before graphql and without graphql (API is on /graphql and login is on /login)

    I use a similar setup and I can give you more info if you need it ;)