My FeedDiscussionsHeadless CMS
New
Sign in
Log inSign up
Learn more about Hashnode Headless CMSHashnode Headless CMS
Collaborate seamlessly with Hashnode Headless CMS for Enterprise.
Upgrade ✨Learn more
Add A Simple Authentication To Your React App

Add A Simple Authentication To Your React App

Deactivated User's photo
Deactivated User
·Nov 28, 2019

Today, I will show you how you can add a simple authentication to your react application that uses authentication from Okta which is a user management system that can be used across multiple apps built on multiple language or frameworks.  

It is similar to Auth0. You can use it across multiple apps and you can even use it with the apps built on different languages and platforms.   Currently Okta supports the following languages:

  • Android
  • Angular
  • iOS
  • Java
  • .NET
  • Node.js
  • PHP
  • React  

1. Sign-Up

Before you can integrate Okta into your react application, you will need a Okta developer account. So go ahead and create your free account right now.   Free Okta Developer Account  

2. Okta Dashboard

After creating your free account, you will be redirected to the dashboard. Did you notice the Org URL in the dashboard. You will need that for your application. The dashboard also has user metrics and system logs that shows all the activities.

Alt Text  

3. Register Your React Application

Its time to register your react application. Click on the Applications link on the dashboard.

  • Click on Add Application
  • Choose Single Page App
  • Add a name to your app in the Name field

Now, you have to edit the Base URI's field. I am going to assume that you are using create-react-app on your local server.

http://localhost:3000

Same thing with Login redirect URIs & Click Done

http://localhost:3000/implicit/callback

Now your application is registered and you will get a Client ID  

4. Fire up your code editor

  • Navigate to your project folder

  • Add the necessary packages

yarn add react-router-dom @okta/okta-react @okta/signin-widget

For the sake of this example, let's assume that your react application has three pages which are in private routes and only authorized user's have access to this routes.

/home /user /order  

5. Create a Login component

  Create a new folder called auth in your components folder and create a new file called Login.js with the following code.

*Login.js*

import React, { Component } from 'react';
import { Redirect } from 'react-router-dom';
import OktaSignInWidget from './SigninWidget';
import { withAuth } from '@okta/okta-react';

export default withAuth(class Login extends Component {
  constructor(props) {
    super(props);
    this.state = {
      authenticated: null
    };
    this.checkAuthentication();
  }

  async checkAuthentication() {
    const authenticated = await this.props.auth.isAuthenticated();
    if (authenticated !== this.state.authenticated) {
      this.setState({ authenticated });
      this.props.history.push('/home')

    }
  }

  componentDidUpdate() {
    this.checkAuthentication();
  }

  onSuccess = (res) => {
    if (res.status === 'SUCCESS') {
      return this.props.auth.redirect({
        sessionToken: res.session.token
      });
   } else {
    // The user can be in another authentication state that requires further action.
    // For more information about these states, see:
    //   https://github.com/okta/okta-signin-widget#rendereloptions-success-error
    }
  }

  onError = (err) => {
    console.log('error logging in', err);
  }

  render() {
    if (this.state.authenticated === null) return null;
    return this.state.authenticated ?
      <Redirect to={{ pathname: '/' }}/> :
      <OktaSignInWidget
        baseUrl={this.props.baseUrl}
        onSuccess={this.onSuccess}
        onError={this.onError}/>;
  }
});

 

Next up, you need to create a new file called SigninWidget in the same auth directory with the following code.

*SigninWidget.js*

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import OktaSignIn from '@okta/okta-signin-widget';
import '@okta/okta-signin-widget/dist/css/okta-sign-in.min.css';

 class SigninWidget extends Component {
  componentDidMount() {
    const el = ReactDOM.findDOMNode(this);
    this.widget = new OktaSignIn({
      baseUrl: this.props.baseUrl,
      authParams: {
        pkce: true
      },
    });
    this.widget.renderEl({el}, this.props.onSuccess, this.props.onError);
  }

  componentWillUnmount() {
    this.widget.remove();
  }

  render() {
    return <div />;
  }
};

export default SigninWidget

 

Next step is to update your route file. Here is an example from my Okta implementation. Wrap private routes inside SecureRoute component and also replace Client ID and issuer with your own credentials from Okta developer console.

import React from "react";
import { BrowserRouter as Router, Route } from "react-router-dom";
import Order from "./pages/Order.js";
import Home from "./pages/Home.js";
import Users from "./pages/Users.js";
import Login from "./components/auth/Login";
import { Security, SecureRoute, ImplicitCallback } from "@okta/okta-react";

function onAuthRequired({ history }) {
  history.push("/login");
}

const AppRoute = () => (
  <Router>
    <Security
      issuer="https://dev-944example.okta.com/oauth2/default" //Replace with your ORG URI.
      clientId="0oa1ws12avokObj45C357example" //Replace with your own client id
      redirectUri={window.location.origin + "/implicit/callback"}
      onAuthRequired={onAuthRequired}
    >
      <SecureRoute exact path="/orders" component={Order} />
      <SecureRoute exact path="/users" component={Users} />
      <Route exact path="/" component={Home} />
      <Route
        path="/login"
        render={() => <Login baseUrl="https://dev-968924.okta.com" />}
      />
      <Route path="/implicit/callback" component={ImplicitCallback} />
    </Security>
  </Router>
);

export default AppRoute;

 

6. Create a Logout function

This is the final step. You'll want to create a logout button in your home.js file or root file which is rendered to the user after logging in and don't forget to wrap your function inside withAuth to use the auth props.


import { withAuth } from "@okta/okta-react";
import Breadcrumb from './breadcrumb.js'
class Home extends Component {
  logout = async () => {
    this.props.auth.logout("/");
  };

  render() {
    return (
      <>
        <Breadcrumb home="Logout" click={this.logout} />
      </>
    );
  }
}

export default withAuth(Home);

 

7. Congratulations! 🎉

If you manage to reach this far, then I hope you have successfully integrated Okta authentication in your react application. If you run into any trouble, shoot a comment below. I will help you solve it.

This is my first post here. I will be back with a new one soon.

Thank you!