Create simple POS with React, Node and MongoDB #2: Auth state, Logout, Update Profile

 

Create simple POS with React, Node and MongoDB #2: Auth state, Logout, Update Profile

Create simple POS with React, Node and MongoDB #2: Auth state, Logout, Update Profile

This is the second chapter of our series of creating a simple POS with React, Node, and MongoDB. Today’s tutorial continues from where we left off in the previous chapter: adding register and login functionalities. Today we will add functionalities to handle authentication state and log out. We will also create a user profile where users can update user information.

Handle Auth State

Check if User is Logged In

Inside App.js, add this simple function to check the authentication state of the user.

We need to hide or show the header, sidebar, and footer on the register and login pages depending on whether the user is logged in or not. We use the above function to achieve this.

Create a Secured Route

We want to authorize only the logged in users to visit some of the pages in our app. Unauthenticated users must be redirected to the login page when attempted to visit such a page. Following SecuredRoute component will handle this functionality.

Now place the dashboard component inside a secured route.

When we try to visit the dashboard now, we are redirected to the login page when not logged in.

Login page

Login page

Prevent Logged In User from Visiting the Login Page

Once users have successfully logged in, they must be prevented from visiting the login page again.

componentDidMount

Every time a user tries to visit the login page, we check whether the token is present. If yes, we return the user to the last visited page.

Last visited page

Last visited page

Implement Logout

When a user logs out, we remove the token stored in the browser and redirect the user to the login page. We show the logout option inside the header menu to the logged in users.

To achieve this, first, remove the existing menu and replace it with the following code. It has additional HTML code to show and handle the logout option inside the dropdown menu.

Now we can create the function that handles logging out. The function first prompts the user to confirm logout using a sweet alert. Then, it redirects the user back to the login page.

Import sweetalert and react-router-dom packages to the components/header/header.js file.

We use withRouter to use the browser history API inside this file.

Inside the logout function, first, add a button to confirm or cancel the logout request. We use a switch to define button texts and values. If the confirm option is selected, the user is redirected to the login page after removing the token. Otherwise, nothing will be changed.

You can see how the logout functionality works in our app.

Logout functionality

Logout functionality

Update User Profile

In this section, we will implement a profile page that allows updating of user data.

Create a new component named profile. Open the profile.js file.

Frontend

We can reuse the code from register.js and copy the required CSS code from AdminLTE example. Add first name, last name, phone number, and address fields to the profile. In the next chapter, we will provide more options for the user to update.

Add a hidden form to handle the user id to be able to identify the user at form submission.

Update the Yup validation function as the following code shows.

Populate the Form

After loading the form, fill its fields with the stored user data. Here is how we can do this.

Get the User Id from the JWT Token

The only way to identify the logged-in user is the JWT token stored in the local storage. If you can remember, we stored the user id inside the JWT token during token creation. However, this data is encrypted. So we need to decode the data to retrieve the associated user id. Following parseJwt function decodes the token and returns the user id.

Now, create a function that store the user id returned from the above function in the component state.

On componentDidMount event, retrieve the user id and get user data.

Attach the state to Formik initialValues variable to populate the form using the data retrieved after loading the page.

Backend

In the backend, add the route that sends user data.

You can see how the profile page now looks like.

re populate profile page

Re populate profile page

Handle Form Submission and Avatar

Now we can get back to the task at our hand: uploading an avatar, storing user data, and displaying the user profile.

In the frontend, we add a new form field to the Formik object to add a file using the setFieldValue option.\

When the form is submitted, we will create a new form object and append the form data including the uploaded file.

We have to update the AJAX request that submits the form to use a PUT request instead of POST.

Backend

Now we have to update the user schema to add the new data fields.

We have to add a few new packages to handle the submitted data. Formidable handles the form object. Path and fs packages handle file management.

Also, we have to create a new public directory to store the images.

We add a function to handle the form submission. Formidable can be used to parse form data.

We need another function to handle file upload.

First, we will rename the avatar image and move it to a directory of our choice. We add the logic to create such a directory if it does not exist. Lastly, we update the user’s data stored in the database.


Resulting profile page

Resulting profile page

The resulting profile page can be seen here.

When a user picks an image for the form, we need to show its preview to the user. When the user reloads the profile page, the uploaded image or a default image must appear on the top.

We will create a new function named showPreviewImage. It listens to the file picker event of the file_obj form field and shows a default image if no image is picked.

This is our completed profile page.

Completed profile page

Completed profile page

When the user visits the profile page after updating the user data, it must show the avatar on the top of the page.

We can easily implement this by updating the src attribute with the avatar attribute of the user object.


prevent redirect back to login

Prevent redirect back to login

Now we will see the following page when we visit the user profile.

Conclusion

In this chapter, we learned how to check the authentication state of a user. We also handled the user logout functionality. We created a new user profile page where a user can update user data and upload an avatar. In the next chapter, we will implement how to send an account activation email and handle account activation. You will learn how to establish an email pipeline where we can communicate with customers to inform about new promotions or send daily reports. Here you can find the GitHub repo for this chapter.

Credit

Protected routes and authentication with React Router v4
Icon made by Pixel perfect from www.flaticon.com

Previous lessons

Create a Simple POS with React, Node and MongoDB #0: Initial Setup Frontend and Backend
Create a simple POS with React, Node and MongoDB #1: Register and Login with JWT

About the author

Stay Informed

It's important to keep up
with industry - subscribe!

Stay Informed

Looks good!
Please enter the correct name.
Please enter the correct email.
Looks good!

Related articles

Create Simple POS With React, Node and MongoDB #4: Optimize App and Setup Deployment Workflow

This is the list of the tasks we have to complete during this chapter: separate backend and frontend, add environment variables to the backend, add ...

Create simple POS with React, Node and MongoDB #3: setup E-mail pipeline with add activate on SignUp

This is the third chapter of our series of developing a POS with React, Node, and MongoDB. In this chapter, we are going to set up an email ...

Create a simple POS with React, Node and MongoDB #1: Register and Login with JWT

This is the second chapter of our series of creating a simple POS using React, Node, and ...

3 comments

Elliot Hughes January 22, 2020 at 3:35 pm
0

 Hey, thanks, is this authentification handling works for POS only, or pretty much for any kind of app?

 
Krissanawat Kaewsanmuang January 23, 2020 at 9:58 am
1

 Yup you can use for any kind app but now I build for POS app

Benoit Tremblay February 3, 2020 at 6:37 pm
0

 Every time an authentication token is saved in the local storage, a kitten is killed. You can read a lot about why this is insecure, especially if the token is long-lived (30 days in your example). Sometimes it’s the only way but it is rarely the case. Secure and httpOnly cookies are preffered but they are really tricky. Also refresh token is a must if you are going to save it for a long time.

I still appreciate what you are trying to teach, keep it up! Authentication is very hard to get right and not beginner friendly 😫.

Sign in

Forgot password?

Or use a social network account

 

By Signing In \ Signing Up, you agree to our privacy policy

Password recovery

You can also try to

Or use a social network account

 

By Signing In \ Signing Up, you agree to our privacy policy