React JS and DRF — JWT Login and Register

Sjlouji
5 min readSep 7, 2020

What is JWT?

JWT is an open standard for transferring data securely between two parties. It is used with authentication systems to make authenticated requests. It is mainly composed of header, payload, and signature. JWT is a stateless authentication mechanism i.e it maintains sessions in the client-side itself instead of storing it in the server.

I have already demonstrated how to create a simple JWT auth API with Django Rest Framework which will be used here as the auth API Endpoint.

  1. Creating React App and Initial Setup

Initially, let’s create a new React App. Also, check if everything is fine with the created project.

npx create-react-app jwtreact
cd jwtreact/
npm start

Now let’s install all the required packages.

a. react-router-dom — For routing

b. react-bootstrap — For Styling our components

c. Axios — For making Request

npm i react-router-dom
npm install react-bootstrap bootstrap
npm i axios

src/index.js

Once installing every package, add the below line in the index.js file which initializes bootstrap.

import 'bootstrap/dist/css/bootstrap.min.css';

Now, to begin with, I am creating Four pages inside the src/Pages folder.

a. Dashboard Page — Page where the user will be redirected after login.

b. Login Page — Page to check if the credentials of the user are correct

b. Login Pag

c. Register Page — Page where the new user stores their data to the server.

d. 404 Page — Page which is used to handle garbage routes.

Once done, create the routes inside the main file which is App.js.

src/App.js

import React from 'react';
import logo from './logo.svg';
import './App.css';
import { Route, Switch, BrowserRouter as Router } from 'react
router-dom';
import Login from './Pages/Login'
import NotFound from './Pages/NotFound'
import Register from './Pages/Register'
import Dashboard from './Pages/Dashboard'
function App() {
return (
<Router>
<Switch>
<Route exact path="/" component={Dashboard} />
<Route path="/login" component={Login} />
<Route path="/register" component={Register} />
<Route component={NotFound} />

</Switch>
</Router>
);
}
export default App;

2. Creating Our Views

We need an App bar to navigate within pages right. So I am using the basic Navbar by react-bootstrap.

src/App.js

import { Navbar, Nav, NavDropdown } from 'react-bootstrap'<Router>
<Navbar bg="dark" variant="dark" expand="lg">
<Navbar.Brand href="#home">React-JWT Login</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="mr-auto">
<Nav.Link href='/login'>Login</Nav.Link>
<Nav.Link href='/register'>Register</Nav.Link>
</Nav>
</Navbar.Collapse>
</Navbar>

<Switch>
<Route exact path="/" component={Dashboard} />
<Route path="/login" component={Login} />
<Route path="/register" component={Register} />
<Route component={NotFound} />
</Switch>
</Router>

Also, here I am using the basic login and register pages provided by bootstrap. You can style it in your own way if you want.

src/Pages/Login.js

import React, { Component } from 'react'
import { Form, Button, Container } from 'react-bootstrap'
export default class Login extends Component {constructor(props) {
super(props);
this.state = {
email: '',
password: '',
};

this.onChange = this.onChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
onChange = (e) => this.setState({ [e.target.name]: e.target.value });handleSubmit(event) {
console.log(this.state.email)
console.log(this.state.password)
event.preventDefault();
}
render() {
return (
<Container style={{ marginTop: '100px' }}>
<Form>
<Form.Group controlId="formBasicEmail" style={{ width: '300px' }}>. <Form.Label>Email address</Form.Label>
<Form.Control type="text" placeholder="Enter email" name="email" value={this.state.email} onChange={this.onChange}/>
</Form.Group>

<Form.Group controlId="formBasicPassword" style={{ width: '300px' }}>
<Form.Label>Password</Form.Label>
<Form.Control type="password" placeholder="Password" name="password" value={this.state.password} onChange={this.onChange}/>
</Form.Group>

<Form.Group controlId="formBasicCheckbox">
<Form.Check type="checkbox" label="Check me out" />
</Form.Group>

<Button variant="primary" type="submit" onClick={this.handleSubmit}>
Submit
</Button>
</Form>
</Container>
)
}
}

URL — http://localhost:3000/login

Login Page UI

src/Pages/Register.js

import React, { Component } from 'react'
import { Form, Button, Container } from 'react-bootstrap'
export default class Register extends Component {constructor(props) {
super(props);
this.state = {
first_name: '',
last_name: '',
email: '',
password: '',

};
this.onChange = this.onChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
onChange = (e) => this.setState({ [e.target.name]: e.target.value });handleSubmit(event) {
console.log(this.state.first_name)
console.log(this.state.last_name)
console.log(this.state.email)
console.log(this.state.password)
event.preventDefault();
}
render() {
return (
<Container style={{ marginTop: '100px' }}>
<Form>
<Form.Group controlId="formBasicFirstName" style={{ width: '300px' }}>
<Form.Label>First name</Form.Label>
<Form.Control type="text" placeholder="Enter First Name" name="first_name" value={this.state.first_name} onChange={this.onChange}/>
</Form.Group>
<Form.Group controlId="formBasicLastName" style={{ width: '300px' }}>
<Form.Label>Last Name</Form.Label>
<Form.Control type="text" placeholder="Enter Last Name" name="last_name" value={this.state.last_name} onChange={this.onChange}/>
</Form.Group>
<Form.Group controlId="formBasicEmail" style={{ width: '300px' }}>
<Form.Label>Email address</Form.Label>
<Form.Control type="text" placeholder="Enter email" name="email" value={this.state.email} onChange={this.onChange}/>
</Form.Group>
<Form.Group controlId="formBasicPassword" style={{ width: '300px' }}>
<Form.Label>Password</Form.Label>
<Form.Control type="password" placeholder="Password" name="password" value={this.state.password} onChange={this.onChange}/>
</Form.Group>
<Button variant="primary" type="submit" onClick={this.handleSubmit}>
Register
</Button>
</Form>
</Container>
)
}
}

URL — http://localhost:3000/register

Register Page

3. Making Auth Request to the API

To make a request to the API, I am Axios which is a React library that helps to make all types of requests. Pass all the value to the URL http://localhost:8000/account/api/register with the required parameters. This stores all our data to the server.

src/Pages/Register.js

handleSubmit(event) {
axios.post('http://localhost:8000/account/api/register',{
username: this.state.email,
password: this.state.password,
first_name: this.state.first_name,
last_name: this.state.last_name
})
.then(function (res){
console.log(res)
localStorage.setItem('token', res.data.access);
localStorage.setItem('user', res.config.data);
}).catch(function (err){
console.log(err)
})
event.preventDefault();
}

Do the same for Login also. Just change the URL to http://localhost:8000/api/token/. This will check if the credentials are right.

src/Pages/Login.js

handleSubmit(event) {
axios.post('http://localhost:8000/api/token/',{
username: this.state.email,
password: this.state.password,
}).then(function (res){
console.log(res)
localStorage.setItem('token', res.data.access);
localStorage.setItem('user', res.config.data);
}).catch(function (err){
console.log(err)
})
event.preventDefault();
}

Now we have logged in, but other pages should know that we have logged in right. To do that, we can store the token in the local storage of the device. In the handleSubmit function, I am storing both the token and the user details to the local storage. So that I can access the token and user details anywhere within the project as I did below.

src/Pages/Dashboard.js

import React, { Component } from 'react'
import { Redirect } from 'react-router-dom'
export default class Dashboard extends Component {
render() {
if(!localStorage.getItem('token')){
return <Redirect to='login'/>
}

return (
<div>
{localStorage.getItem('user')}
</div>
)
}
}
Dashboard Page

Feel free to contact me for any queries.

Email: sjlouji10@gmail.com

Linkedin: https://www.linkedin.com/in/sjlouji/

The complete code can be found on my Github: https://github.com/sjlouji/JWT-login-register-Medium

Happy coding…

--

--

Sjlouji

Software Engineer at @Pando. Developer | Writer. From ABC to the world of code.