Setup authentication & authorization in Reactjs

In this Tutorial you will learn how to Setup authentication & authorization in Reactjs , we will also build an example app with authentication & authorization .

preview of our app

setup-authentication-authorization-in-reactjs

Let’s start by making a folder structure separating the functionality. Create a folder called actions within the source folder and add a file called login.js; then, add this code:

'use strict';
import fetch from 'isomorphic-fetch';

Fetch is a new interface for fetching resources. It will be recognizable if you’ve used XMLHttpRequest in the past or Superagent with Promises . The new API supports Promises out of the box, supporting a generic definition of Request and Responseobjects. It also provides a definition for concepts such as Cross-Origin Resource Sharing (CORS) and HTTP Origin header semantics.

We could have used Fetch right out of the box with Babel, but this package is preferable because it adds Fetch as a global function that has a consistent API for use in both server and client code. . Consider the following code:

export const LOGIN_USER = 'LOGIN_USER';

This defines a single action constant that we can use when we want to dispatch the action. Now check this out:

export function login(userData) {

With this, we create and export a single function called login that accepts a userData object. Now we’ll create a body variable that holds the username and password:

const body = { username: userData.username,
password: userData.password };

This is not strictly necessary as we can easily pass the userData object along, but the idea is that by making it explicit, we’re sending a username and password and nothing else. This will be easy to understand when you look at the next chunk of code:

const options = {headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer 1234567890'
},
method: 'post',
body: JSON.stringify(body)
}

We will send the POST request with an Accept header and Content-Type, both specifying that we’re working with JSON data. We’ll also send an authorization header with a bearer token.

Recommended :  Complete Guide to Working With Forms In Reactjs

The body is passed through the JSON.stringify() method because we can’t send a raw JavaScript object through HTTP. The method converts an object to a proper JSON representation, optionally replacing values if a replacer function is specified. Check this out:

return dispatch => {
return fetch(`http://dunebookapp-useradmin.herokuapp.com/v1/login`, options)
.then(response => response.json())
.then(json => dispatch(setLoginDetails(json)))
}
}

This is the return section of our login function. It first connects to our login API through the fetchfunction, which returns a Promise.

function setLoginDetails(json) {
if(json.length ===  ) {
return {
type: LOGIN_FAIL,
timestamp: Date.now()
}
}
return {
type: LOGIN_USER,
loginResponse: json,
timestamp: Date.now()
}
}

If json contains a valid response, setLoginDetails returns an action object with a type that maps to the LOGIN_USER string value and two custom values. Remember that an action must always return a type and that anything else it returns is optional and up to you. If the json parameter is empty, the function returns LOGIN_FAIL.

Now create lets Create a reducer

The next file we’re going to add is a reducer. We’ll put it in a folder of its own. So create a folder called reducers within source and add a file called login.js (same as the action), then add this code:

'use strict';
import {
LOGIN_USER,
LOGIN_FAIL
} from '../actions/login';
import { combineReducers } from 'redux'

We’ll import the file we just created as well as the combineReducer() method from Redux. We’ll only create one reducer for now, but I like to add it from the start since it’s typical to add more reducers as the app grows. It generally makes sense to have a root file to combine reducers as the number of your reducers grow. Next, we’ll declare a function that expects a state object and action as its arguments:

function user(state = {
message: "",
userData: {}
}, action){

When action.type returns a successful state, we return the state and add or update the userDataand timestamp parameters:

switch(action.type) {
case LOGIN_USER:
return {
...state,
userData: action.loginResponse[],
timestamp: action.timestamp
};

Note that in order to use the spread operator in our reducer, we need to add a new preset to our .babelrc configuration. This is not part of EcmaScript 6 but is proposed as an extension to the language. Open up your terminal and run this command:

npm install save-dev babel-preset-stage-2

Next, modify the presets section in .babelrc so that it looks like this:

"presets": ["react", "es2015", "stage-2"]

We’ll also add a case in case there is a failure to log the user in:

case LOGIN_FAIL:
return {
...state,
userData: [],
error: "Invalid login",
timestamp: action.timestamp
};

Finally, we’ll add a default case. It’s not strictly necessary, but it’s generally prudent to handle any unforeseen cases like this:

default:
return state
}
}
const rootReducer = combineReducers({user});
export default rootReducer

Lets Create a store

The next file we’re going to add is a store. Create a folder called stores within your source folder, add the store.js file, and then add this code:

'use strict';
import rootReducer from '../reducers/login';

We’ll import the reducer we just created:

import { persistState } from 'redux-devtools';
import { compose, createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import DevTools from '../devtools';

 

About the author

Deven Rathore

I'm Deven Rathore, a multidisciplinary & self-taught designer with 3 years of experience. I'm passionate about technology, music, coffee, traveling and everything visually stimulating. Constantly learning and experiencing new things.

Pin It on Pinterest

Shares