Displaying session data and signing out

Linked Projects:

Calreact
 
Lesson code: 

Backend Rails API - https://github.com/learnetto/calreact/tree/m9l3-devise-token-auth

Frontend React app - https://github.com/learnetto/calreact-frontend/tree/m9l4-sign-out

In this lesson, we’ll add a way to indicate when a user is logged in and a way to sign out.

We’ll display the logged in user’s email address and a sign-out link at the top.

We’ll do that in the AppHeader component.

Let’s start off by converting AppHeader into a class in AppHeader.js.

And let’s change the import statement in AppRouter for this component.

Now let’s check if a user exists in the session. To do that, in render in AppHeader.js, we'll state

{sessionStorage.getItem(‘user’) && (
)}

We’ll return  the <p> tag and inside that

render () {
  		if(sessionStorage.getItem('user')) {
  			return (
  				<div>
  						<p>
  							{JSON.parse(sessionStorage.getItem('user')).uid}
 
That’ll be the email address.

And then let’s add a logout link underneath:

<a href=“#”>Sign out </a>

Alright, let’s see this in the browser.

[screenshot 1:03-4]

We can see the email address and sign-out link at the top.

Now let’s make the logout link functional.

Let’s add information to our Sign out call:

<a href="#" onClick={this.handleSignOut} >Sign out</a>

and let’s define that up at the top of the page:

export default class AppHeader extends React.Component {

handleSignout = (e) => {

e.preventDefault();

$.ajax

type: DELETE

url: http://localhost:3001/auth/sign_out

data: JSON.parse(sessionStorage.user

.done

If the sign out call is successful, we want to remove the user data from the session.

So let’s do

sessionStorage.removeItem(‘user’)

and then redirect to the login route. To do that, use

this.props.history.push(‘/login’)

All these lines go into the 

handleSignout = (e) => {

And let’s not forget to import jQuery by updating the code at the top of the page:

import React from 'react';
import { Link, Redirect } from 'react-router-dom';
import $ from jquery

Now, let’s test this route.

Click on the Sign out link and we get redirected to login.

Now if I click on the title, I’m taken to the homepage.

[screenshot 2:29]

But we don’t want this to load.

If the user is not signed in, we want to redirect to the login route.

And that applies not just to the homepage, but to all routes.

Since the AppHeader is shared among all our routes, let’s do that redirect logic in there.

We could also do it in AppRouter but it’ll be easier to do it in AppHeader.

Let’s import the Redirect component from react-router-dom. This component gives us a convenient way to do the redirect.

import { Link, Redirect } from 'react-router-dom';

Let’s take the check for the user item in session and turn it into an if else statement:

if(sessionStorage.getItem('user')) {

If the user is signed in, we’ll just return this bit of markup:

if(sessionStorage.getItem('user')) {
 			return (
  				<div>
  						<p>
  							{JSON.parse(sessionStorage.getItem('user')).uid}
  							<a href="#" onClick={this.handleSignOut} >Sign out</a>
  						</p>
  					<Link to='/'>
  						<h1>CalReact</h1>
 					</Link>
  				</div>
  			)

  Else, we’ll return:

	} else {
  			return (
  				<Redirect to='/login' />
  			)
  		}
 	}
 } 

Then try to see whether the app works. Now if I go to the homepage, I’m redirected to login.

Let’s log in and we get redirected to the homepage. And again, we can sign out.

One last thing we want to do is validate the session user data, to make sure we don’t use any expired headers or invalid session data.

We can do that calling the validate_token endpoint in componentDidMount in our AppHeader component.

So when the component renders, we first validate the session and then proceed further.

Let’s do

export default class AppHeader extends React.Component {
  
  	componentDidMount () {
  		$.ajax({
  			type: 'GET',
  			url: 'http://localhost:3001/auth/validate_token',
        dataType: "JSON",
        headers: JSON.parse(sessionStorage.getItem('user'))
  		})

If the validation fails, then we’ll redirect to the login page:

headers: JSON.parse(sessionStorage.getItem('user'))
  		})
  		.fail((data) => {
  			this.props.history.push('/login');
  		})
  	}

That should take care of validating our session token.

Now let’s try the app in the browser again.

Let’s sign in... We get redirected to the homepage. Let’s create a new appointment. Enter a title, choose a date, submit. It gets added. We can view it, edit it, delete it.

But we haven’t added the headers to the delete call in AppointmentForm yet.

Let’s do that. In deleteAppointment, paste in the headers in this AJAX call:

 deleteAppointment = () => {
   if(confirm("Are you sure you want to delete this appointment?")) {
   $.ajax({
          type: "DELETE",
          url: `http://localhost:3001/appointments/${this.props.match.params.id}`,
          headers: JSON.parse(sessionStorage.getItem('user'))
        })

Now let’s try again - and it works.

All of the features of our app now work with user authentication.

Liked this tutorial? Get more like this in your inbox