Sign Up & Sign In with Rails/React/Redux/Hooks-Part 1

User Authentication with JWT — JSON Web Tokens

Osha Groetz
5 min readMar 21, 2021

JSON Web Tokens (JWT)… What are they and why do we use them?

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object.¹ The content inside the JWT (pronounced ‘jot’ if you can believe it!) can be trusted and verified because it’s digitally signed (JWS, RFC 7515). The signature in our use case will be generated by using symmetric keys (HMAC algorithms). Default JWT (which is what the below example will show) are NOT encrypted, but JWT can carry encrypted data (JWE, RFC 7516) to protect sensitive information. The string in our JWT object that is sent from the server to our client will be a base64url encoded serialization, which is easily decoded to see the plain JSON content of the token.²

Ruby on Rails Backend / Server

Because I really want to focus this blog on the frontend Redux/Hooks aspect of User Auth (I found a lack of info on this), I will only be posting images just below of the backend controllers. It is extremely important, of course, to understand what’s actually happening in our backend code. There is a GREAT article by Reinald Reynoso that will break all of this down for you here. I wanted to make sure that if you’re following along and would like all the information in one place, it’s available to you, but I learned everything to code the backend routes/methods through Reinald’s blog. (Thank you Reinald Reynoso!) *Please note that I have the backend setup following API Namespace conventions, so all of the controllers, with exception of the application controller, and the routes, again with exception of application routes, are placed in folders controllers > api > v1. See image directly below

Routes — User Model — Controller SetUp (follows API NameSpace Convention)
Application Controller
Auth Controller
Users Controller

React.js Frontend / Client

We are going to build the frontend components as Functional components. If you need a quick breakdown of the React Hook ‘useState’, see my post here. For a refresher on Redux (action and reducers) with the Hooks ‘useSelector’ and ‘useDispatch’ see my post from last week here.

THE SIGNUP COMPONENT

In my own application I have a navbar component that imports in two child components (sign up and sign in) that each render a button of the same name. These buttons, when clicked, each render a pop up with their corresponding simple sign up or sign in forms.

Although I know it would be much cleaner to actually have a separate component of an imported form into this file, for blog space sake our sign up form will look like this:

Let’s break down a few things in the code above:

  1. Import useState from react to be able to work with state in a functional component
  2. I created a history file that wraps around my entire application that allows me to navigate between components in my SPA without a page refresh. The use of that history can be seen above on line 52.
  3. Import useSelector and useDispatch from react-redux so that you can use dispatch in your functional component — directly replacing the ‘mapDispatchToProps’ function available in class components. useSelector will replace ‘mapStateToProps’ and if you need it, will give you direct access to the store and the state that is held in it
  4. On line 6, I am importing signupUser, which is the action file/function that we will need to trigger redux.
  5. Continuing down in the file, we useState along with the users input into the form to capture and store the state of the values of each input field. I broke them up to work around the simple issue that it was easier than building a useState object to change.
  6. Next we have Line 31 where we set a variable ‘dispatch’ for our useDispatch hook. On Line 44, inside of our handleSubmit function, we wrap our action with this dispatch.
  7. The rest of the handleSubmit function is pretty straightforward, resetting our states back to their empty, original values, which will clear out the form fields in turn.
  8. Lines 55–57 are an example of how to call to the redux store to access our new user, although I don’t use the new user data in this component.

THE SIGN UP ACTION FILE

Refresher: Actions are the only source of information for the store as per Redux official documentation. It carries a payload of information from your application to store. As discussed earlier, actions are plain JavaScript object that must have a type attribute to indicate the type of action performed.³

The signupUser function above, (thank you Redux Thunk), will set off an async chain of events to our Users route in our backend Users controller. The method is POST because we are creating a new user. THE MOST IMPORTANT LINE OF CODE here to me is Line 29. If the data comes back to us from Rails and our user was created and is valid, set our JWT item in localStorage.

For each event in this chain, we have a different action.type (for example POST_USER_SUCCESS which we always hope we get). Whatever our action.type happens to be, we are immediately sent into our reducer and taking along our type and payload (whatever data we received back from our backend).

THE REDUCER

Once we make it through our action function, one way or another (success or failure), we now head into our reducer file with our action type and payload.

Through the switch/case statements, our program matches the case with the action.type and executes the code in that block accordingly. If, for example, the type is POST_USER_SUCCESS, we set state to our action.payload.user, etc, and return a copy of state.

PLEASE REMEMBER…although a user has been successfully signed up, and the reducer has added the user to our ‘store’, we are not persisting this store to any database, and as such, if a page reload/refresh were to happen, we would lose the userReducer state immediately…What’s important to us is that that glorious token exists in our local storage…that’s the key in our next step of this process.

Be back shortly with Part 2 — User Login / User Auto-Login & User Sign Out

  1. Introduction to JSON Web Tokens | “https://jwt.io/introduction
  2. JSON Web tokens (JWT): how to use them safely | Hector Hurtado Ruesga | “https://www.bbva.com/en/json-web-tokens-jwt-how-to-use-them-safely/
  3. Redux-Actions | “https://www.tutorialspoint.com/redux/redux_actions.htm

--

--

Osha Groetz

Software Engineer. React, Javascript, Typescript, HTML, CSS, Ruby, Ruby On Rails