React okta

npm

npm versionbuild status

Okta React SDK builds on top of the Okta Auth SDK.

This SDK is a toolkit to build Okta integration with many common "router" packages, such as react-router, reach-router, and others.

Users migrating from version 1.x of this SDK that required react-router should see Migrating from 1.x to learn what changes are necessary.

With the Okta Auth SDK, you can:

  • Login and logout from Okta using the OAuth 2.0 API
  • Retrieve user information
  • Determine authentication status
  • Validate the current user's session

All of these features are supported by this SDK. Additionally, using this SDK, you can:

This SDK does not provide any UI components.

This SDK does not currently support Server Side Rendering (SSR)

This library currently supports:

Release Status

The current stable major version series is:

VersionStatus
Stable
Stable
Retiring on 2021-12-09
Retiring on 2021-08-20
Retired
Retired

The latest release can always be found on the [releases page][github-releases].

Getting Started

  • If you do not already have a Developer Edition Account, you can create one at https://developer.okta.com/signup/.
  • An Okta Application, configured for Single-Page App (SPA) mode. This is done from the Okta Developer Console. When following the wizard, use the default properties. They are are designed to work with our sample applications.

Helpful Links

Installation

This library is available through npm.

Install

npm install --save @okta/okta-react

Install peer dependencies

npm install --save react npm install --save react-dom npm install --save react-router-dom npm install --save @okta/okta-auth-js

Usage

provides the means to connect a React SPA with Okta OIDC information. Most commonly, you will connect to a router library such as react-router.

React-Router components (optional)

provides a number of pre-built components to connect a -based SPA to Okta OIDC information. You can use these components directly, or use them as a basis for building your own components.

  • SecureRoute - A normal except authentication is needed to render the component.

General components

provides the necessary tools to build an integration with most common React-based SPA routers.

  • Security - Accepts oktaAuth instance (required) and additional configuration as props. This component acts as a React Context Provider that maintains the latest authState and oktaAuth instance for the downstream consumers. This context can be accessed via the useOktaAuth React Hook, or the withOktaAuth Higher Order Component wrapper from it's descendant component.
  • LoginCallback - A simple component which handles the login callback when the user is redirected back to the application from the Okta login site. accepts an optional prop that will be used to format the output for any error in handling the callback. This component will be passed an prop that is an error describing the problem. (see the component for the default rendering)

Users of routers other than can use useOktaAuth to see if is not null and is true. If it is false, you can send them to login via oktaAuth.signInWithRedirect(). See the implementation of as an example.

Available Hooks

These hooks can be used in a component that is a descendant of a component ( provides the necessary context). Class-based components can gain access to the same information via the Higher Order Component, which provides and as props to the wrapped component.

  • useOktaAuth - gives an object with two properties:
    • - the Okta Auth SDK instance.
    • - the AuthState object that shows the current authentication state of the user to your app (initial state is ).

Minimal Example in React Router

Create Routes

This example defines 3 routes:

  • / - Anyone can access the home page
  • /protected - Protected is only visible to authenticated users
  • /login/callback - This is where auth is handled for you after redirection

Note: Make sure you have the url (absolute url) added in your Okta App's configuration.

A common mistake is to try and apply an authentication requirement to all pages, THEN add an exception for the login page. This often fails because of how routes are evaluated in most routing packages. To avoid this problem, declare specific routes or branches of routes that require authentication without exceptions.

Creating React Router Routes with class-based components

// src/App.jsimportReact,{Component}from'react';import{BrowserRouterasRouter,Route,withRouter}from'react-router-dom';import{SecureRoute,Security,LoginCallback}from'@okta/okta-react';import{OktaAuth,toRelativeUrl}from'@okta/okta-auth-js';importHomefrom'./Home';importProtectedfrom'./Protected';classAppextendsComponent{constructor(props){super(props);this.oktaAuth=newOktaAuth({issuer: 'https://{yourOktaDomain}.com/oauth2/default',clientId: '{clientId}',redirectUri: window.location.origin+'/login/callback'});this.restoreOriginalUri=async(_oktaAuth,originalUri)=>{props.history.replace(toRelativeUrl(originalUri||'/',window.location.origin));};}render(){return(<SecurityoktaAuth={this.oktaAuth}restoreOriginalUri={this.restoreOriginalUri}><Routepath='/'exact={true}component={Home}/><SecureRoutepath='/protected'component={Protected}/><Routepath='/login/callback'component={LoginCallback}/></Security>);}}constAppWithRouterAccess=withRouter(App);exportdefaultclassextendsComponent{render(){return(<Router><AppWithRouterAccess/></Router>);}}

Creating React Router Routes with function-based components

importReactfrom'react';import{SecureRoute,Security,LoginCallback}from'@okta/okta-react';import{OktaAuth,toRelativeUrl}from'@okta/okta-auth-js';import{BrowserRouterasRouter,Route,useHistory}from'react-router-dom';importHomefrom'./Home';importProtectedfrom'./Protected';constoktaAuth=newOktaAuth({issuer: 'https://{yourOktaDomain}.com/oauth2/default',clientId: '{clientId}',redirectUri: window.location.origin+'/login/callback'});constApp=()=>{consthistory=useHistory();constrestoreOriginalUri=async(_oktaAuth,originalUri)=>{history.replace(toRelativeUrl(originalUri||'/',window.location.origin));};return(<SecurityoktaAuth={oktaAuth}restoreOriginalUri={restoreOriginalUri}><Routepath='/'exact={true}component={Home}/><SecureRoutepath='/protected'component={Protected}/><Routepath='/login/callback'component={LoginCallback}/></Security>);};constAppWithRouterAccess=()=>(<Router><App/></Router>);exportdefaultAppWithRouterAccesss;

Show Login and Logout Buttons (class-based)

// src/Home.jsimportReact,{Component}from'react';import{withOktaAuth}from'@okta/okta-react';exportdefaultwithOktaAuth(classHomeextendsComponent{constructor(props){super(props);this.login=this.login.bind(this);this.logout=this.logout.bind(this);}asynclogin(){this.props.oktaAuth.signInWithRedirect();}asynclogout(){this.props.oktaAuth.signOut('/');}render(){if(!this.props.authState)return<div>Loading...</div>;returnthis.props.authState.isAuthenticated ? <buttononClick={this.logout}>Logout</button> : <buttononClick={this.login}>Login</button>;}});

Show Login and Logout Buttons (function-based)

// src/Home.jsconstHome=()=>{const{ oktaAuth, authState }=useOktaAuth();constlogin=async()=>oktaAuth.signInWithRedirect();constlogout=async()=>oktaAuth.signOut('/');if(!authState){return<div>Loading...</div>;}if(!authState.isAuthenticated){return(<div><p>Not Logged in yet</p><buttononClick={login}>Login</button></div>);}return(<div><p>Logged in!</p><buttononClick={logout}>Logout</button></div>);};exportdefaultHome;

Use the Access Token (class-based)

When your users are authenticated, your React application has an access token that was issued by your Okta Authorization server. You can use this token to authenticate requests for resources on your server or API. As a hypothetical example, let's say you have an API that provides messages for a user. You could create a component that gets the access token and uses it to make an authenticated request to your server.

Here is what the React component could look like for this hypothetical example:

importfetchfrom'isomorphic-fetch';importReact,{Component}from'react';import{withOktaAuth}from'@okta/okta-react';exportdefaultwithOktaAuth(classMessageListextendsComponent{constructor(props){super(props)this.state={messages: null}}asynccomponentDidMount(){try{constresponse=awaitfetch('http://localhost:{serverPort}/api/messages',{headers: {Authorization: 'Bearer '+this.props.authState.accessToken}});constdata=awaitresponse.json();this.setState({messages: data.messages});}catch(err){// handle error as needed}}render(){if(!this.state.messages)return<div>Loading...</div>;constitems=this.state.messages.map(message=><likey={message}>{message}</li>);return<ul>{items}</ul>;}});

Use the Access Token (function-based)

When your users are authenticated, your React application has an access token that was issued by your Okta Authorization server. You can use this token to authenticate requests for resources on your server or API. As a hypothetical example, let's say you have an API that provides messages for a user. You could create a component that gets the access token and uses it to make an authenticated request to your server.

Here is what the React component could look like for this hypothetical example:

importfetchfrom'isomorphic-fetch';importReact,{useState,useEffect}from'react';import{useOktaAuth}from'@okta/okta-react';exportdefaultMessageList=()=>{const{ authState }=useOktaAuth();const[messages,setMessages]=useState(null);useEffect(()=>{if(authState.isAuthenticated){constapiCall=async()=>{try{constresponse=awaitfetch('http://localhost:{serverPort}/api/messages',{headers: {Authorization: 'Bearer '+authState.accessToken.accessToken}});constdata=awaitresponse.json();setMessages(data.messages);}catch(err){// handle error as needed}}apiCall();}},[authState]);if(!messages)return<div>Loading...</div>;constitems=messages.map(message=><likey={message}>{message}</li>);return<ul>{items}</ul>;};

Reference

is the top-most component of okta-react. It accepts oktaAuth instance and addtional configuration options as props.

oktaAuth

(required) The pre-initialized oktaAuth instance. See Configuration Reference for details of how to initialize the instance.

restoreOriginalUri

(required) Callback function. Called to restore original URI during oktaAuth.handleLoginRedirect() is called. Will override restoreOriginalUri option of oktaAuth

onAuthRequired

(optional) Callback function. Called when authentication is required. If this is not supplied, redirects to Okta. This callback will receive oktaAuth instance as the first function parameter. This is triggered when a SecureRoute is accessed without authentication. A common use case for this callback is to redirect users to a custom login route when authentication is required for a SecureRoute.

Example

import{useHistory}from'react-router-dom';import{OktaAuth,toRelativeUrl}from'@okta/okta-auth-js';constoktaAuth=newOktaAuth({issuer: 'https://{yourOktaDomain}.com/oauth2/default',clientId: '{clientId}',redirectUri: window.location.origin+'/login/callback'});exportdefaultApp=()=>{consthistory=useHistory();constcustomAuthHandler=(oktaAuth)=>{// Redirect to the /login page that has a CustomLoginComponent// This example is specific to React-Routerhistory.push('/login');};constrestoreOriginalUri=async(_oktaAuth,originalUri)=>{history.replace(toRelativeUrl(originalUri||'/',window.location.origin));};return(<SecurityoktaAuth={oktaAuth}onAuthRequired={customAuthHandler}restoreOriginalUri={restoreOriginalUri}><Routepath='/login'component={CustomLoginComponent}>{/* some routes here */}</Security> ); };

PKCE Example

Assuming you have configured your application to allow the grant type, you can implement the PKCE flow with the following steps:

  • Initialize [oktaAuth](Okta Auth SDK) instance (with default PKCE configuration as ) and pass it to the component.
  • add route with LoginCallback component to handle login redirect from OKTA.
import{OktaAuth}from'@okta/okta-auth-js';constoktaAuth=newOktaAuth({issuer: 'https://{yourOktaDomain}.com/oauth2/default',clientId: '{clientId}',redirectUri: window.location.origin+'/login/callback',});classAppextendsComponent{render(){return(<SecurityoktaAuth={oktaAuth}restoreOriginalUri={restoreOriginalUri}><Routepath='/'exact={true}component={Home}/><Routepath='/login/callback'component={LoginCallback}/></Security>);}}

ensures that a route is only rendered if the user is authenticated. If the user is not authenticated, it calls onAuthRequired if it exists, otherwise, it redirects to Okta.

accepts as an optional prop, it overrides onAuthRequired from the Security component if exists.

integrates with . Other routers will need their own methods to ensure authentication using the hooks/HOC props provided by this SDK.

As with from , can take one of:

  • a prop that is passed a component
  • a prop that is passed a function that returns a component. This function will be passed any additional props that react-router injects (such as or )
  • children components

handles the callback after the redirect to and back from the Okta-hosted login page. By default, it parses the tokens from the uri, stores them, then redirects to . If a caused the redirect, then the callback redirects to the secured route. For more advanced cases, this component can be copied to your own source tree and modified as needed.

errorComponent

By default, LoginCallback will display any errors from . If you wish to customise the display of such error messages, you can pass your own component as an prop to . The value will be passed to the as the prop.

loadingElement

By default, LoginCallback will display nothing during handling the callback. If you wish to customize this, you can pass your React element (not component) as prop to . Example:

onAuthResume

When an external auth (such as a social IDP) redirects back to your application AND your Okta sign-in policies require additional authentication factors before authentication is complete, the redirect to your application redirectUri callback will be an error.

An error is an indication that you should resume the authentication flow. You can pass an function as a prop to , and the will call the function when an error is returned to the redirectUri of your application.

If using the Okta SignIn Widget, redirecting to your login route will allow the widget to automatically resume your authentication transaction.

// Example assumes you are using react-router with a customer-hosted Okta SignIn Widget on your /login route// This code is wherever you have your <Security> component, which must be inside your <Router> for react-routerconstonAuthResume=async()=>{history.push('/login');};return(<SecurityoktaAuth={oktaAuth}restoreOriginalUri={restoreOriginalUri}><Switch><SecureRoutepath='/protected'component={Protected}/><Routepath='/login/callback'render={(props)=><LoginCallback{...props}onAuthResume={onAuthResume}/>}/><Routepath='/login'component={CustomLogin}/><Routepath='/'component={Home}/></Switch></Security>);

is a higher-order component which injects an oktaAuth instance and an authState object as props into the component. Function-based components will want to use the hook instead. These props provide a way for components to make decisions based on authState or to call Okta Auth SDK methods, such as or . Components wrapped in need to be a child or descendant of a component to have the necessary context.

is a React Hook that returns an object containing the authState object and the oktaAuth instance. Class-based components will want to use the withOktaAuth HOC instead. Using this hook will trigger a re-render when the authState object updates. Components calling this hook need to be a child or descendant of a component to have the necessary context.

Using

importReactfrom'react';import{useOktaAuth}from'@okta/okta-react';exportdefaultMyComponent=()=>{const{ authState }=useOktaAuth();if(!authState){return<div>Loading...</div>;}if(authState.isAuthenticated){return<div>Hello User!</div>;}return<div>You need to login</div>;};

Migrating between versions

Migrating from 5.x to 6.x

6.x requires 5.x (see notes for migration). Some changes affects :

  • Initial is null
  • Removed from
  • Default value for is null

Migrating from 4.x to 5.x

From version 5.0, the Security component explicitly requires prop restoreOriginalUri to decouple from . Example of implementation of this callback for :

import{Security}from'@okta/okta-react';import{useHistory}from'react-router-dom';import{OktaAuth,toRelativeUrl}from'@okta/okta-auth-js';constoktaAuth=newOktaAuth({issuer: 'https://{yourOktaDomain}.com/oauth2/default',clientId: '{clientId}',redirectUri: window.location.origin+'/login/callback'});exportdefaultApp=()=>{consthistory=useHistory();constrestoreOriginalUri=async(_oktaAuth,originalUri)=>{history.replace(toRelativeUrl(originalUri,window.location.origin));};return(<SecurityoktaAuth={oktaAuth}restoreOriginalUri={restoreOriginalUri}>{/* some routes here */}</Security>);};

Note: If you use prop for , use this implementation to fix duplication problem:

import{toRelativeUrl}from'@okta/okta-auth-js';constrestoreOriginalUri=async(_oktaAuth,originalUri)=>{constbasepath=history.createHref({});constoriginalUriWithoutBasepath=originalUri.replace(basepath,'/');history.replace(toRelativeUrl(originalUriWithoutBasepath,window.location.origin));};

Migrating from 3.x to 4.x

Updating the Security component

From version 4.0, the Security component starts to explicitly accept oktaAuth instance as prop to replace the internal instance. You will need to replace the Okta Auth SDK related configurations with a pre-initialized oktaAuth instance.

Note
  • is now a peer dependency for this SDK. You must add as a dependency to your project and install it separately from .
  • still accept onAuthRequired as a prop.
import{OktaAuth}from'@okta/okta-auth-js';import{Security}from'@okta/okta-react';constoktaAuth=newOktaAuth(oidcConfig);exportdefault()=>(<SecurityoktaAuth={oktaAuth}onAuthRequired={customAuthHandler}> // children component </Security>);

Replacing authService instance

The module has been removed since version 4.0. The useOktaAuth hook and withOktaAuth HOC are exposing instead of .

  • Replace with when use useOktaAuth

    import{useOktaAuth}from'@okta/okta-react';exportdefault()=>{const{ oktaAuth, authState }=useOktaAuth();// handle rest component logic};
  • Replace with when use withOktaAuth

    import{withOktaAuth}from'@okta/okta-react';exportdefaultwithOktaAuth((props)=>{// use props.oktaAuth});

Replacing authService public methods

The instance exposes similar public methods to handle logic for the removed module.

  • is removed

    This method called , if it was set in the config options, or if no option was set. If you had code that was calling this method, you may either call your function directly or .

  • is replaced by

  • is replaced by

    accepted either a string or an object as options. signOut accepts only an options object.

    If you had code like this:

    authService.logout('/goodbye');

    it should be rewritten as:

    oktaAuth.signOut({postLogoutRedirectUri: window.location.origin+'/goodbye'});

    Note that the value for must be an absolute URL. This URL must also be on the "allowed list" in your Okta app's configuration. If no options are passed or no is set on the options object, it will redirect to after sign out is complete.

  • and have been changed to synchronous methods

    With maintaining in-memory AuthState since Okta Auth SDK version 4.1, token values can be accessed in synchronous manner.

  • is replaced by

    is called by the component as the last step of the login redirect authorization flow. It will obtain and store tokens and then call which will return the browser to the which was set before the login redirect flow began.

  • related methods have been collected in Okta Auth SDK AuthStateManager

    • Change to
    • Change to
    • Change to
    • , and have been removed
  • By default will be true if both accessToken and idToken are valid

    If you have a custom function which implements the default logic, you should remove it.

  • has been removed

    You may access the with the property:

    consttokens=oktaAuth.tokenManager.getTokens();

Migrating from 2.x to 3.x

See breaking changes for version 3.0

Migrating from 1.x to 2.0

The 1.x series for this SDK required the use of react-router. These instructions assume you are moving to version 2.0 of this SDK and are still using React Router (v5+)

Replacing Security component

The component is now a generic (not router-specific) provider of Okta context for child components and is required to be an ancestor of any components using the hook, as well as any components using the Higher Order Component.

has been renamed .

The prop to the component is now . The other prop options to have not changed from the 1.x series to the 2.0.x series

Replacing the withAuth Higher-Order Component wrapper

This SDK now provides authentication information via React Hooks (see useOktaAuth). If you want a component to receive the auth information as a direct prop to your class-based component, you can use the wrapper where you previously used the wrapper. The exact props provided have changed to allow for synchronous access to authentication information. In addition to the object prop (previously ), there is also an object prop that has properties for the current authentication state.

Replacing , , and inside a component

Two complications of the 1.x series of this SDK have been simplified in the 2.x series:

  • These functions were asynchronous (because the retrieval layer underneath them can be asynchronous) which made avoiding race conditions in renders/re-renders tricky.
  • Recognizing when authentication had yet to be decided versus when it had been decided and was not authenticated was an unclear difference between , , and .

To resolve these the object holds the authentication information and provides it synchronously (following the first async determination) as an object. While waiting on that first determination, the object is null. When the authentication updates the authService object will emit an event after which a new authState object is available.

Any component that was using to get the object and called the properties above has two options to migrate to the new SDK:

  1. Replace the use of with withOktaAuth(), and replace any of these asynchronous calls to the methods with the values of the related authState properties. OR
  2. Remove the use of and instead use the useOktaAuth() React Hook to get the authService and authState objects. Any use of the methods (, , and ) should change to use the already calculated properties of authState.

To use either of these options, your component must be a descendant of a component, in order to have the necessary context.

These changes should result in less complexity within your components as these values are now synchronously available after the initial determination.

If you need access to the instance directly, it is provided by withOktaAuth() as a prop or is available via the useOktaAuth() React Hook. You can use the examples in this README to see how to use authService to perform common tasks such as login/logout, or inspect the provided component to see an example of the use of the managing the redirect from the Okta site.

Updating your ImplicitCallback component

  • If you were using the provided ImplicitCallback component, you can replace it with
  • If you were using a modified version of the provided ImplicitCallback component, you will need to examine the new version to see the changes. It may be easier to start with a copy of the new LoginCallback component and copy your changes to it. If you want to use a class-based version of LoginCallback, wrap the component in the [withOktaAuth][] HOC to have the authService and authState properties passed as props.
  • If you had your own component that handled the redirect-back-to-the-application after authentication, you should examine the new LoginCallback component as well as the notes in this migration section about the changes to , , and .

Contributing

We welcome contributions to all of our open-source packages. Please see the contribution guide to understand how to structure a contribution.

Development

Installing dependencies for contributions

We use yarn for dependency management when developing this package:

Commands

CommandDescription
Install dependencies
Start the sample app using the SDK
Run unit and integration tests
Run eslint linting tests
Sours: https://www.npmjs.com/package/@okta/okta-react

Add an Okta sign in widget with React

Okta has been growing over 45% year over year since 2017, and it doesn’t seem to be slowing down.

Big and small companies are using Okta for their external and internal software tools.

Okta is a user authentication management tool that helps businesses manage their employees software accounts with their company software tools.

For example, let’s say I own a cat store and I use Slack, Jira, and Github.

If I hire an engineer, I’ll have to create multiple accounts for that specific engineer.

And if that engineer leaves, I’ll have to go through each tool and remove that person account. This is a problem.

Instead of doing all that manual work, you can integrate all those software tools to an Okta account and assign an Okta user to a software tool.

That means you can create 1 Okta user to your Okta account, and Okta will handle adding and removing an account for all your software tools that you’ve integrated with.

The neat part about Okta is that you can implement it to your own internal applications.

In this article I’ll go over 8 easy steps to adding Okta authentication to your React application.

Step 1: Create Okta account

First step is to head over to the okta.com and create an account.

You can create a free 30 day trial account to test on. But if you have one already go to step 2.

That’s pretty easy.

You will than receive an email with your log in credentials, and a link to the log in page.

Go ahead and log in, and set your new password.

Step 2: Create an Okta app

Once you’re logged in, you’ll need to head over to the application page.

You can find that under the Application menu tab when you hover over it.

There is also a shortcut link to add a new application on the right side.

But if you’re in the application page then click Add Application next.

Then click on Create New App. It should be a green button on the left hand side.

A popup will be presented, and you’ll need to add the following configuration to fit your React application.

You will than be prompted to add some basic setting configuration about your app.

For the moment you can add your current localhost and port number for for your test app.

Click Save once those are added.

In the bottom page of your Okta app you’ll find your Client ID.

Click on the right button to copy it to your clipboard.

Step 3: Assign user to Okta app

The next step is to assign a user to your Okta app.

If a Okta user is not assigned to that app, they will get denied.

That’s okay too if you want. But at least add yourself!

Go back to the application page and click on the Assign Application button.

Select your application and the user you want to assign it too and click Next.

And click the confirmation button right after.

Step 4: Add trusted origin to Okta

The last configuration that you need to do in your Okta account is to add your trusted origins.

This will make sure we can avoid any CORS issues.

Hover over the Security menu and select the API sub menu item.

The first tab you’ll see in the page is about tokens, but we want to change that to Trusted Origins tab.

And select Add Origin next.

Add the following field values onto the form and click Save.

The boring stuff has been completed. Now the coding begins.

Step 5: Create React app

To keep this example guide simple I’m going to use Create React App tooling to help us get quicker to the important part of this guide.

Let’s create a directory called okta-sample.

Inside our new directory, create a package.json file and add the following.

Now you may install those dependencies by running .

Let’s also create a directory called public and src in the root of the project.

Inside the public directory let’s add an index.html file.

The index.html file will serve as a basic skeleton for the app.

In the src directory, all of your React code will live in there.

Inside src, create 2 files called index.js, and App.js. You’ll also need to add a pages directory inside the src directory.

Go ahead and run . It should boot up a browser window pointed to localhost:3000.

And the web page should blank.

Step 6: Create the index file

In this file we’re doing a handful of actions here.

We’re initializing the Browser router and adding Okta’s Security component.

Which allows you to supply your Okta configurations to your React app.

P.S. don’t hardcode production configurations like in this example.

The issuer property is just the base URL to your Okta page. Don’t forget to add the slash () in the end.

The redirect_uri, and client_id can be grabbed from the Okta application page.

If you’re running your app locally during this step you might see your application broken.

That’s because App.js hasn’t been created or the routes. Let’s do that next.

Step 7: Create App.js file

In this file you’ll see how will put the pieces together.

The first step is to import React, React Router DOM modules called , and .

is going to help us define public routes.

And we’re going to use to help us build an easy 2 menu item navigation.

The first link will be pointing to the home page page which is the log in page.

The second link will help you go to the admin dashboard page.

The other important part to this file is the component that is provided by Okta.

This component helps you do the logic whether the user is allowed to enter the page. This is determined if the user is authenticated or not.

The last important piece to this file is the Okta React component.

This component helps handle the response after Okta tells React if the user has successfully signed in or not.

Step 8: Creating the admin dashboard & login page

The admin dashboard will be a file in the pages directory called AdminDashboard.js.

It’s a very simple and plain functional React component.

The next file to create is for our home page. Which will display a sign in button.

In the login importing Okta’s HOC(higher order component) called .

And I’m wrapping it around the React class component .

This is important because provides new property to your React component called user .

In the example above you can see that I’m using a method called login inside a event for the button.

Inside the you can see that I’m testing some of the other functionality that comes with such as checking if the user is authenticated, and getting the user information.

also provides other functionality such as:

  • getIdToken
  • logout
  • getAccessToken
  • handleAuthentication

Conclusion

Congratulations you’ve added Okta authentication to your React application!

Here’s the link to the source code. And if you found it interesting and helpful please give it a start!

Github source link

I like to tweet about React and post helpful code snippets. Follow me there if you would like some too!

Sours: https://linguinecode.com/post/add-okta-authentication-to-react-app
  1. Jabra earbuds
  2. Wire kennel
  3. Moebius models
  4. Wow mods
  5. Fabfilter pro

Okta React SDK

npm versionbuild status

Okta React SDK builds on top of the Okta Auth SDK.

This SDK is a toolkit to build Okta integration with many common "router" packages, such as react-router, reach-router, and others.

Users migrating from version 1.x of this SDK that required react-router should see Migrating from 1.x to learn what changes are necessary.

With the Okta Auth SDK, you can:

  • Login and logout from Okta using the OAuth 2.0 API
  • Retrieve user information
  • Determine authentication status
  • Validate the current user's session

All of these features are supported by this SDK. Additionally, using this SDK, you can:

This SDK does not provide any UI components.

This SDK does not currently support Server Side Rendering (SSR)

This library currently supports:

Release Status

The current stable major version series is:

VersionStatus
Stable
Stable
Retiring on 2021-12-09
Retiring on 2021-08-20
Retired
Retired

The latest release can always be found on the [releases page][github-releases].

Getting Started

  • If you do not already have a Developer Edition Account, you can create one at https://developer.okta.com/signup/.
  • An Okta Application, configured for Single-Page App (SPA) mode. This is done from the Okta Developer Console. When following the wizard, use the default properties. They are are designed to work with our sample applications.

Helpful Links

Installation

This library is available through npm.

Install

npm install --save @okta/okta-react

Install peer dependencies

npm install --save react npm install --save react-dom npm install --save react-router-dom npm install --save @okta/okta-auth-js

Usage

provides the means to connect a React SPA with Okta OIDC information. Most commonly, you will connect to a router library such as react-router.

React-Router components (optional)

provides a number of pre-built components to connect a -based SPA to Okta OIDC information. You can use these components directly, or use them as a basis for building your own components.

  • SecureRoute - A normal except authentication is needed to render the component.

General components

provides the necessary tools to build an integration with most common React-based SPA routers.

  • Security - Accepts oktaAuth instance (required) and additional configuration as props. This component acts as a React Context Provider that maintains the latest authState and oktaAuth instance for the downstream consumers. This context can be accessed via the useOktaAuth React Hook, or the withOktaAuth Higher Order Component wrapper from it's descendant component.
  • LoginCallback - A simple component which handles the login callback when the user is redirected back to the application from the Okta login site. accepts an optional prop that will be used to format the output for any error in handling the callback. This component will be passed an prop that is an error describing the problem. (see the component for the default rendering)

Users of routers other than can use useOktaAuth to see if is not null and is true. If it is false, you can send them to login via oktaAuth.signInWithRedirect(). See the implementation of as an example.

Available Hooks

These hooks can be used in a component that is a descendant of a component ( provides the necessary context). Class-based components can gain access to the same information via the Higher Order Component, which provides and as props to the wrapped component.

  • useOktaAuth - gives an object with two properties:
    • - the Okta Auth SDK instance.
    • - the AuthState object that shows the current authentication state of the user to your app (initial state is ).

Minimal Example in React Router

Create Routes

This example defines 3 routes:

  • / - Anyone can access the home page
  • /protected - Protected is only visible to authenticated users
  • /login/callback - This is where auth is handled for you after redirection

Note: Make sure you have the url (absolute url) added in your Okta App's configuration.

A common mistake is to try and apply an authentication requirement to all pages, THEN add an exception for the login page. This often fails because of how routes are evaluated in most routing packages. To avoid this problem, declare specific routes or branches of routes that require authentication without exceptions.

Creating React Router Routes with class-based components

// src/App.jsimportReact,{Component}from'react';import{BrowserRouterasRouter,Route,withRouter}from'react-router-dom';import{SecureRoute,Security,LoginCallback}from'@okta/okta-react';import{OktaAuth,toRelativeUrl}from'@okta/okta-auth-js';importHomefrom'./Home';importProtectedfrom'./Protected';classAppextendsComponent{constructor(props){super(props);this.oktaAuth=newOktaAuth({issuer: 'https://{yourOktaDomain}.com/oauth2/default',clientId: '{clientId}',redirectUri: window.location.origin+'/login/callback'});this.restoreOriginalUri=async(_oktaAuth,originalUri)=>{props.history.replace(toRelativeUrl(originalUri||'/',window.location.origin));};}render(){return(<SecurityoktaAuth={this.oktaAuth}restoreOriginalUri={this.restoreOriginalUri}><Routepath='/'exact={true}component={Home}/><SecureRoutepath='/protected'component={Protected}/><Routepath='/login/callback'component={LoginCallback}/></Security>);}}constAppWithRouterAccess=withRouter(App);exportdefaultclassextendsComponent{render(){return(<Router><AppWithRouterAccess/></Router>);}}

Creating React Router Routes with function-based components

importReactfrom'react';import{SecureRoute,Security,LoginCallback}from'@okta/okta-react';import{OktaAuth,toRelativeUrl}from'@okta/okta-auth-js';import{BrowserRouterasRouter,Route,useHistory}from'react-router-dom';importHomefrom'./Home';importProtectedfrom'./Protected';constoktaAuth=newOktaAuth({issuer: 'https://{yourOktaDomain}.com/oauth2/default',clientId: '{clientId}',redirectUri: window.location.origin+'/login/callback'});constApp=()=>{consthistory=useHistory();constrestoreOriginalUri=async(_oktaAuth,originalUri)=>{history.replace(toRelativeUrl(originalUri||'/',window.location.origin));};return(<SecurityoktaAuth={oktaAuth}restoreOriginalUri={restoreOriginalUri}><Routepath='/'exact={true}component={Home}/><SecureRoutepath='/protected'component={Protected}/><Routepath='/login/callback'component={LoginCallback}/></Security>);};constAppWithRouterAccess=()=>(<Router><App/></Router>);exportdefaultAppWithRouterAccesss;
Sours: https://github.com/okta/okta-react

npm

npm versionbuild status

The Okta React Native library makes it easy to add authentication to your React Native app. This library is a wrapper around Okta OIDC Android and Okta OIDC iOS.

This library follows the current best practice for native apps using:

This library also exposes APIs to interact with Authentication API directly to implement native UI for authentication. The library supports two flows in your React Native application:

  • Browser Sign In - redirects the user to the Okta browser login page of your Org for authentication. The user is redirected back to the React Native application after authenticating.
  • Custom Sign In - A React Native application that adopts native authorization to take control over authorization flow and/or provide custom UI.

You can learn more on the Okta + ReactNative page in our documentation. You can also download our sample applications.

Prerequisites

  • If you do not already have a Developer Edition Account, you can create one at https://developer.okta.com/signup/.
  • If you don't have a React Native app, or are new to React Native, please continue with the React Native CLI Quickstart guide. It will walk you through the creation of a React Native app and other application development essentials.
  • If you are developing with an Android device emulator, make sure to check out the React Native - Android Development setup instructions.

Configure an OpenID Connect Client in Okta

In Okta, applications are OpenID Connect clients that can use Okta Authorization servers to authenticate users. Your Okta Org already has a default authorization server, so you just need to create an OIDC client that will use it.

  • Log into the Okta Developer Dashboard, click Applications then Add Application.
  • Choose Native as the platform, then submit the form the default values, which should look similar to this:
SettingValue
App NameMy Native App
Login redirect URIscom.mynative.app:/
Grant Types AllowedAuthorization Code, Refresh Token

After you have created the application there are two more values you will need to gather:

SettingWhere to Find
Client IDIn the applications list, or on the "General" tab of a specific application.
Org URLOn the home screen of the developer dashboard, in the upper right.

Note:As with any Okta application, make sure you assign Users or Groups to the OpenID Connect Client. Otherwise, no one can use it.

These values will be used in your React application to setup the OpenID Connect flow with Okta.

Getting started

This library is available through npm. To install it, simply add it to your project:

iOS Setup

To setup iOS, there are three steps that you must take.

  1. Make sure your iOS app's deployment target is and above.
  2. Install Okta Open ID Connect iOS.
  3. Make sure you also configure Swift.

Set iOS Deployment Target

This library supports iOS version and above. Go to your project -> -> , and set it to at least version .

Install Okta Open ID Connect iOS

This library depends on the native Okta OIDC iOS library. It is not distributed as part of the React Native library to keep your dependency management consistent.

You can currently add Okta OIDC iOS through CocoaPods:

  1. CocoaPods

    React Native >= 0.60: With React Native 0.60 pods are added to automatically. Run the commands to install dependencies:

    React Native < 0.60: Make sure your looks like this:

    Then run .

  2. Carthage With Carthage, add the following line to your Cartfile:

    Then run .

    Open project settings and choose your application target. Then open and add from into section

Android Setup

For Android, there are two steps that you must take:

  1. Installing Okta Open Id Connect Android.
  2. Add a redirect scheme to your project.

Install Okta Open ID Connect Android

This library depends on the native Okta OIDC Android library. You have to add this library through Gradle. Follow the following steps:

  1. Add this line to , under -> .

  2. Make sure your is in .

Add redirect scheme

Defining a redirect scheme to capture the authorization redirect. In , under -> , add:

Usage

You will need the values from the OIDC client that you created in the previous step to set up. You will also need to know your Okta Org URL, which you can see on the home page of the Okta Developer console.

Before calling any other method, it is important that you call to set up the configuration properly on the native modules.

Importing methods would follow this pattern:

import{createConfig,signIn,signOut,getAccessToken}from'@okta/okta-react-native';

This method will create a configured client on the native modules. Resolves if successfully configures a client.

  • is an optional field in config, for more information please refer to About the Issuer.
  • is a configurable setting only on Android devices. If you're a developer testing on Android emulators, set this field to .
  • is an optional field in config, and is used only by Android for the Chrome Custom Tabs color for the OIDC flow.
  • is an optional field in config, and is used only by Android to match all Chrome Custom Tabs browsers.
  • is an optional field in config, represented in seconds. Available on iOS and Android.
  • is an optional field in config, represented in seconds. Available only on Android.
awaitcreateConfig({issuer: "https://{yourOktaDomain}/oauth2/default",// OptionalclientId: "{clientId}",redirectUri: "{redirectUri}",endSessionRedirectUri: "{endSessionRedirectUri}",discoveryUri: "https://{yourOktaDomain}",scopes: ["openid","profile","offline_access"],requireHardwareBackedKeyStore: true,// OptionalandroidChromeTabColor: "#FF00AA",// OptionalbrowserMatchAll: true,// OptionalhttpConnectionTimeout: 15,// OptionalhttpReadTimeout: 10,// Optional});

This method will return an instance of client to communicate with Okta Authentication API. For more information, please checkout Okta AuthJs Node JS and React Native Usage section.

This method will handle both and scenarios based on provided options.

This async method will automatically redirect users to your Okta organziation for authentication. It will emit an event once a user successfully signs in. Make sure your event listeners are mounted and unmounted. Note: on iOS there isn't a event. If the sign in process is cancelled, will be triggered.

leverages device's native browser to automatically redirect users to your Okta organziation for authentication. By providing no argument, this method will trigger the flow. It will emit an event once a user successfully signs in. Make sure your event listeners are mounted and unmounted.

Note: on iOS there isn't a event. If the sign in process is cancelled, will be triggered.

awaitsignInWithBrowser();

Note: IDP can be passed by specifying an argument with the idp parameter.

awaitsignInWithBrowser({idp: 'your_idp_here'});

Note: If you want to get rid of the system sign in and sign out alert on iOS, then pass the parameter when calling . The cookies will not be retained by the browser, so after logging out the user will be prompted to re-authenticate.

awaitsignInWithBrowser({noSSO: true});
Sample Usage
signInWithBrowser({noSSO: true}).then(result=>{// Consume accessToken from result.access_token}).catch(error=>{// { code: "", message: "", detail: { message: "", status: "" } }// handle error})

provides the way to authenticate the user within the native application. By providing object with username and password fields, this method will retrieve then exchange it for . Both and are supported. This method is leveraging SDK to perform authentication API request. For more information, please checkout Okta AuthJs signIn options section.

Sample Usage
signIn({username: "{username}",password: "{password}"}).then(token=>{// consume accessToken from token.access_token}).catch(error=>{// { code: "", message: "", detail: { message: "", status: "" } }// handle error})
Sample Usage
import{signIn,EventEmitter}from'@okta/okta-react-native';componentDidMount(){this.signInSuccess=EventEmitter.addListener('signInSuccess',function(e: Event){console.log(e.access_token);// Do something ...});this.signOutSuccess=EventEmitter.addListener('signOutSuccess',function(e: Event){//...});this.onError=EventEmitter.addListener('onError',function(e: Event){//...});this.onCancelled=EventEmitter.addListener('onCancelled',function(e: Event){//...});}componentWillUnmount(){this.signInSuccess.remove();this.signOutSuccess.remove();this.onError.remove();this.onCancelled.remove();}

If you already logged in to Okta and have a valid session token, you can complete authorization by calling method. It will emit an event once a user successfully signs in. Make sure your event listeners are mounted and unmounted. Note: on iOS there isn't a event. If the process is cancelled, will be triggered.

awaitauthenticate({sessionToken: sessionToken});

Clears the browser session and the app session (stored tokens) in memory. Fires an event once a user successfully logs out. For sample usage, refer to .

Note: This method apply for browser-sign-in scenario only. Use a combination of (optional) and methods to sign out when use custom-sign-in.

browser-sign-in sample

custom-sign-in sample

awaitrevokeAccessToken();// optionalawaitrevokeIdToken();// optionalawaitclearTokens();

Returns a promise that resolves to if there is a valid Access token and ID token. Otherwise .

Note: This does not mean that the Access and the ID tokens are fresh - just that they were valid the last time they were used. You should introspect the tokens to get know whether they are valid at the time being.

Sample Response

If authenticated:

{"authenticated": true}

This method returns a promise that will return the access token as a string. If no access token is available (either does not exist, or expired), then the promise will be rejected.

Sample Response

If the access token is available:

{"access_token": "{accessToken}"}

This method returns a promise that will return the identity token as a string. The promise will be rejected if no ID token is available.

Sample Response

If the ID token is available:

{"id_token": "{idToken}"}

Returns a promise that will fetch the most up-to-date user claims from the OpenID Connect endpoint.

Sample Response

If a user is available:

{"sub": "00uid4BxXw6I6TV4m0g3","name" :"John Doe","nickname":"Jimmy","given_name":"John","middle_name":"James","family_name":"Doe","profile":"https://example.com/john.doe","zoneinfo":"America/Los_Angeles","locale":"en-US","updated_at":1311280970,"email":"[email protected]","email_verified":true,"address" : {"street_address":"123 Hollywood Blvd.","locality":"Los Angeles","region":"CA","postal_code":"90210","country":"US"},"phone_number":"+1 (425) 555-1212"}

Returns the user claims decoded from the identity token.

awaitgetUserFromIdToken();
Sample Response

Sample user claims:

{"sub": "00uid4BxXw6I6TV4m0g3","name": "John Doe","preferred_username": "[email protected]""ver": 1,"iss": "https://dev-example.okta.com","aud": "00uid4BxXw6I6TV4m0g3","auth_time": 1561679776,"exp": 1561683377,"iat": 1561679777,"idp": "00uid4BxXw6I6TV4m0g3"}

Revoke the access token to make it inactive. Resolves if access token has been successfully revoked.

awaitrevokeAccessToken();

Revoke the identity token to make it inactive. Resolves if id token has been successfully revoked.

Revoke the refresh token to make it inactive. Resolves if refresh token has been successfully revoked.

awaitrevokeRefreshToken();

Removes all tokens from local storage. Resolves if tokens were successfully cleared.

Introspect the access token.

awaitintrospectAccessToken();
Sample Response

Sample responses can be found here.

Introspect the ID token.

awaitintrospectIdToken();
Sample Response

Sample responses can be found here.

Introspect the id token.

awaitintrospectRefreshToken();
Sample Response

Sample responses can be found here.

Refreshes all tokens. Resolves with the refreshed tokens.

Sample Response
{"access_token": "{accessToken}","id_token": "{idToken}","refresh_token": "refreshToken"}

Migrating between versions

Migrating from 1.x to 2.x

has a few major changes in API.

  • returns Promise.

Note: Events , are still triggered.

signInWithBrowser().then(result=>{// { resolve_type: 'authorized', access_token: 'token' }}).catch(error=>{// { code: '', message: '', detail: { message: '', status: '' } }})

Note: Events , are still triggered.

signOut().then(result=>{// { resolve_type: 'signed_out' }}).catch(error=>{// { code: '', message: '', detail: { message: '', status: '' } }// Handle error})
  • The event is triggered if a user cancels (closes) a embedded-browser window or tap the button (on iOS). Additionally, and throws the error: .

Troubleshooting

  • .

Solution: Navigate through Terminal to the folder and execute the command: .

Contributing

We welcome contributions to all of our open-source packages. Please see the contribution guide to understand how to structure a contribution.

Installing dependencies for contributions

We use yarn for dependency management when developing this package:

Sours: https://www.npmjs.com/package/@okta/okta-react-native

Okta react

Okta Auth JS and React

This guide will walk you through integrating authentication into a React app with Okta by performing these steps:

This guide is for v5.1.1 and v6.0.0.

Prerequisites

If you do not already have a Developer Edition Account, you can create one at https://developer.okta.com/signup/(opens new window).

Add an OpenID Connect Client in Okta

  • Sign in to the Okta Developer Dashboard, and select Create New App
  • Choose Single Page App (SPA) as the platform, then populate your new OpenID Connect application with appropriate values for your app. For example:
SettingValue
App NameOpenID Connect App (must be unique)
Login redirect URIs
Logout redirect URIs
Allowed grant typesAuthorization Code

Note: It is important to choose the appropriate application type for apps which are public clients. Failing to do so may result in Okta API endpoints attempting to verify an app's client secret, which public clients are not designed to have, hence breaking the sign-in or sign-out flow. Note: CORS is automatically enabled for the granted login redirect URIs.

Create a React App

To create a React app, you can use Create React App(opens new window):

This creates a new project in a folder named and installs all required dependencies.

Install Dependencies

A simple way to add authentication to a React app is using the Okta Auth JS library. You can install it using :

You also need and to manage your routes. You can use to support other router libraries, but has pre-existing support.

Create a Custom Sign-In Form

If the Okta Sign-In Widget doesn't fit your needs, Okta Auth JS provides lower-level access to User Lifecycle operations, MFA, and more. For this example, you create a simple username and password form without MFA.

Create a file:

using a function-based component:

using a class-based component:

Create Routes

Some routes require authentication in order to render. Defining those routes is easy using from . Let's take a look at what routes are needed for this example:

  • : A default page to handle basic control of the app.
  • : A route protected by .
  • : Redirect to the org sign-in page.
  • : A route to parse tokens after a redirect.

First, create to provide links to navigate our app:

using a function-based component:

using a class-based component:

This route will only be visible to users with a valid .

Create a new component :

This route redirects if the user is already logged in. If the user is coming from a protected page, they'll be redirected back to the page upon successful sign in.

Create a new component :

using a function-based component:

using a class-based component:

The component for this route (LoginCallback) comes with . It handles token parsing, token storage, and redirecting to a protected page if one triggered the sign in.

Connect the Routes

Update to include your project components and routes. is the component that controls the authentication flows, so it requires your OpenID Connect configuration. By default, redirects to Okta's sign-in page when the user isn't authenticated.

In this example, is overridden to redirect to the custom sign-in route instead, which requires a component that is a descendent of Router to have access to 's . Other router libraries will have their own methods of managing browser history:

Update to use function-based components:

And, create its companion at . Make sure to replace the placeholders with your Okta values.

You can also update and to use class-based components:

Start your app

Finally, start your app:

Conclusion

You have now successfully authenticated with Okta! Now what? With a user's , you have basic claims for the user's identity. You can extend the set of claims by modifying the to retrieve custom information about the user. This includes , , , and more.

Want to learn how to use the user's ? Check out our React How To Guide to learn about protecting routes on your server, validating the , and more!

Support

Have a question or see a bug? Post your question on the Okta Developer Forum(opens new window).

Edit This Page On GitHub

Sours: https://developer.okta.com/code/react/okta_react/

Okta Sign-In Widget and React

This guide will walk you through integrating authentication into a React app with Okta by performing these steps:

This guide is for v5.7.3, v6.0.0 and v5.1.1.

Prerequisites

If you do not already have a Developer Edition Account, you can create one at https://developer.okta.com/signup/(opens new window).

Add an OpenID Connect Client in Okta

  • Sign in to the Okta Developer Dashboard, and select Create New App
  • Choose Single Page App (SPA) as the platform, then populate your new OpenID Connect app with values similar to:
SettingValue
App NameOpenID Connect App
Login redirect URIs
Logout redirect URIs
Allowed grant typesAuthorization Code

Note: It is important to choose the appropriate application type for apps which are public clients. Failing to do so may result in Okta API endpoints attempting to verify an app's client secret, which public clients are not designed to have, hence breaking the sign-in or sign-out flow.

Note: CORS is automatically enabled for the granted login redirect URIs.

Create a React App

To quickly create a React app, we recommend using Create React App.

If you need more information, see the Create React App getting started guide(opens new window).

Install Dependencies

To provide a fully-featured and customizable sign-in experience, the Okta Sign-In Widget is available to handle User Lifecycle operations, MFA, and more. You can install it using :

You also need , and to manage our routes:

Config

Create a file. Make sure to replace the placeholders with your Okta values.

Create a Widget Wrapper

To render the Sign-In Widget in React, you must create a wrapper that allows you to treat it as a React component.

Create a file:

Create Routes

Some routes require authentication in order to render. Defining those routes is easy using from . Let's take a look at what routes are needed for this example:

  • : A default page to handle basic control of the app.
  • : A route protected by .
  • : Show the sign-in page.
  • : A route to parse tokens after a redirect.

First, create to provide links to navigate our app:

This route will only be visible to users with a valid .

Create a new component :

This route hosts the Sign-In Widget and redirects if the user is already logged in. If the user is coming from a protected page, they'll be redirected back to the page upon login.

Create a new component :

The component for this route (LoginCallback) comes with . It handles token parsing, token storage, and redirecting to a protected page if one triggered the login.

Connect the Routes

Our example is using . By default you can include your components and Routes in . If you need access to particular router properties, such as the object that's used to override the default sign-in flow, you need to create a wrapper component around .

Update to create a Router and call >` as a child component:

Create and include your project components and routes. is the component that controls the authentication flows, so it requires your OpenID Connect configuration. By default, redirects to Okta's sign-in page when the user isn't authenticated. In this example, is overridden to redirect to the custom sign-in route instead:

Start your app

Finally, start your app:

Conclusion

You have now successfully authenticated with Okta! Now what? With a user's , you have basic claims for the user's identity. You can extend the set of claims by modifying the to retrieve custom information about the user. This includes , , , and more.

Want to learn how to use the user's ? Check out our React how to guide to learn about protecting routes on your server, validating the , and more!

Support

Have a question or see a bug? Post your question on the Okta Developer Forum(opens new window).

Edit This Page On GitHub

Sours: https://d28m3l9ryqsunl.cloudfront.net/code/react/okta_react_sign-in_widget/

Now discussing:

Implementing Okta authentication in a React app

Verifying the identity of your users is paramount for most applications. Spinning up your own authentication system can be simple at first, but when you consider security bridges and ease of integration with third-parties such Google or Facebook, you can see how building and maintaining your own authentication system can quickly become tedious and complex.

A good approach would be to use a solution dedicated to handling authentication, such as Okta. Okta gives you access to a dedicated team of security experts so you don’t have to worry about the hassle of tending to your user data.

In this tutorial, we’ll show you how to implement Okta authentication in React. To follow along, you should be familiar with JavaScript and React Hooks.

Setting up a React application

The first requirement is to sign up for the developer edition of Okta. This gives us access to the admin dashboard where we will create the sign-in method and our application type — in our case, a single-page application (SPA).

Application Page To Create A Single-Page Application

Under the application route, we can generate an app integration (our sign-in method).

Applications Creation Page Highlighting Create App Integration Button

Clicking the Create App Integration button generates a dialog with sign-in methods. Since our application is an SPA and we are not connected to a backend, we’ll use the OpenID Connect sign-in method, which provides a sign-in widget for us (we will also build our own custom login form later on).

Pop-Up Confirming A OpenID Connect Sign-In Method

After selecting the application integration, we want to select Single-page Application and proceed.

The next step is to specify a sign-in redirect URI (a callback URI). This is very important because when using the OpenID Connect sign-in method, we are redirected to an Okta-hosted sign-in widget (a different endpoint from our application) and need a callback URL where Okta returns back to our application with the user’s details.

You can also specify other routes, such as the sign-out redirect URI, which is the page to whichthe application should be redirected when we log out of the application. For our use case, we can specify the base URL/login route as our logout endpoint, meaning the user is redirected to the landing page or the login page, depending on endpoint we specify. If you don’t specify an endpoint, the user is redirected to the Okta sign-in widget

Base URI is optional. This is useful if you plan to self-host the Okta Sign-in widget, but outside the scope of this tutorial.

Integration with React

Now that we have our application integration with Okta ready, let’s integrate it with our React application.

When handling this integration, pay extra close attention to the client ID and the Okta domain, both of which can be found in the Application tab.

The first step is to install the Okta SDK and the Okta Auth JavaScript SDK:

# yarn yarn add @okta/okta-auth-js @okta/okta-react # npm npm install --save @okta/okta-auth-js @okta/okta-react

Let’s create environmental variables (in he form of a file) for our Okta configuration data.

OKTA_DOMAIN=<YOUR_OKTA_DOMAIN> CLIENT_ID=<YOUR_CLIENT_ID> CALLBACK_PATH='/login/callback' ISSUER='https://<YOUR_OKTA_DOMAIN>/oauth2/default' HOST='window.location.host' SCOPES='openid profile email'

Now we can configure our application to use Okta.

import React from "react"; import { BrowserRouter as Router, Route, useHistory } from "react-router-dom"; import { Security, SecureRoute } from "@okta/okta-react"; import { OktaAuth, toRelativeUrl } from "@okta/okta-auth-js"; import { LandingPage } from "./LandingPage"; import { Dashboard } from "./Dashboard"; import { Header } from "./Header"; const CLIENT_ID = process.env.CLIENT_ID; const CALLBACK_PATH = process.env.CALLBACK_PATH; const ISSUER = process.env.ISSUER; const HOST = process.env.HOST; const REDIRECT_URI = `http://${HOST}${CALLBACK_PATH}`; const SCOPES = process.env.SCOPES; if (!SCOPES || !CLIENT_ID || !CALLBACK_PATH || !ISSUER || !HOST) { throw new Error("All environmental variables must be set"); } const config = { issuer: ISSUER, clientId: CLIENT_ID, redirectUri: REDIRECT_URI, scopes: SCOPES.split(/\s+/), }; const oktaAuth = new OktaAuth(config); const App = () => { const history = useHistory(); const restoreOriginalUri = async (_oktaAuth: any, originalUri: any) => { history.replace(toRelativeUrl(originalUri || "/", window.location.origin)); }; return ( <Router> <Security restoreOriginalUri={restoreOriginalUri} oktaAuth={oktaAuth}> <Header /> <Route path="/" exact={true} component={LandingPage} /> <SecureRoute path="/dashboard" exact={true} component={Dashboard} /> </Security> </Router> ); }; export default App;

A new instance is created with the config object. This is passed into the security component, which wraps all the routes of our application and provides the and objects to all of its children (the components in the routes).

The object can be used to change or read information about the authentication state.

The object contains:

  • , a boolean that indicates whether the user is authenticated. The value is true if and an are present in the
  • , a JWT access token that is assigned to the current authenticated user
  • , a JWT ID token that is assigned to the current authenticated user
  • , which is returned if the authentication process fails

Notice also that we don’t need to handle a ; Okta provides a route out of the box for that, which protects the path specified.

Lets implement a login button to trigger the sign-in widget. It’s common to have this in the header component, so we’ll handle it there.

We are provided with a hook, which gives us access to the and objects.

import React from "react"; import { useOktaAuth } from "@okta/okta-react"; function Header() { const { authState, oktaAuth } = useOktaAuth(); const loginWithRedirect = () => oktaAuth.signInWithRedirect({ originalUri: "/dashboard" }); const logOut = () => oktaAuth.signOut(); const buttonText = authState.isAuthenticated ? "Logout" : "Login"; const btnLogic = authState.isAuthenticated ? logOut : loginWithRedirect; return ( <> <div>Okta React</div> <button onClick={btnLogic}>{buttonText}</button> </> ); } export { Header };

We’re using the to determine whether we want to log into or sign out of our application.

The function handles the login trigger with a redirect back to the dashboard route on successful login, as shown below:

Okta's Login Page For Users

Upon login, the user is redirected to the dashboard route immediately.

For the logout function to work in localhost, we need to add localhost to the list of our trusted routes. This will allow cross-origin in our application.

Page To Add Trusted Routes

Now if we click on the logout button in the header, it successfully logs our user out and redirects them to the landing page.

We made it! We’ve successfully implemented Okta authentication in a React application.

Custom sign-in form

The Okta login interface is good and easy to get started with, but let’s say we want to implement a custom sign-in form with a unique design and also keep our users on the page without redirecting to Okta.

We can implement this with the provided when we call the hook.

Let’s implement a custom sign-in form:

import React from "react"; import { useOktaAuth } from "@okta/okta-react/bundles/types"; function SignIn() { const { oktaAuth } = useOktaAuth(); const [sessionToken, setSessionToken] = React.useState<string | null>(null); const onSubmit = (event: React.SyntheticEvent<HTMLFormElement>) => { event.preventDefault(); const username = event.currentTarget.elements.namedItem( "username" ) as HTMLInputElement; const password = event.currentTarget.elements.namedItem( "password" ) as HTMLInputElement; const data = { username: username.value, password: password.value, }; oktaAuth .signInWithCredentials(data) .then((res) => { const sessionToken = res.sessionToken; if (!sessionToken) { throw new Error("authentication process failed"); } setSessionToken(sessionToken); oktaAuth.signInWithRedirect({ originalUri: "/dashboard", // @ts-ignore sessionToken: sessionToken, }); }) .catch((err) => console.log("handle error here": err)); }; if (sessionToken) return <div />; return ( <div> <form onSubmit={onSubmit}> <label htmlFor="username">Username</label> <input type="text" id="username" /> <label htmlFor="password">Password</label> <input type="password" id="password" /> <button type="submit">SignIn</button> </form> </div> ); } export { SignIn };

We have our own form and we are making use of the option in to handle a custom form submission. The , a single-use token, is the value received upon successful authentication. The details are still available to us via the ID or access tokens provided in the object when the hook is called.

Upon successful login, we can use the function to send the user to the original URI (mainly the protected dashboard route) and also include the .

Let’s run our application and wire the login button to redirect to this login form endpoint and also update our routes:

import React from "react"; import { useOktaAuth } from "@okta/okta-react"; import { Link } from "react-router-dom"; function Header() { const { authState, oktaAuth } = useOktaAuth(); if (!authState) return null; const logOutRedirect = async () => await oktaAuth.signOut(); function btnToRender() { return authState.isAuthenticated ? ( <button onClick={logOutRedirect}>LogOut</button> ) : ( <button> <Link to="/login">Login</Link> </button> ); } return ( <> <div>Okta React</div> {btnToRender()} </> ); } export { Header };

The routes update as shown below:

<Security restoreOriginalUri={restoreOriginalUri} oktaAuth={oktaAuth}> <Header /> <Route path="/" exact={true} component={LandingPage} /> <Route path="/login" component={SignIn} /> <SecureRoute path="/dashboard" exact={true} component={Dashboard} /> <Route path={CALLBACK_PATH} component={LoginCallback} /> </Security>

Now, when we click on our login button, we are redirected to the login page.

Congratulations! You’ve successfully implemented a custom login screen in your React app with Okta.

Conclusion

User data is very delicate information that, if compromised, can lead to serious privacy issues. In this tutorial, we showed you how to implement a much more secure way to handle the authentication in a React app with Okta.

For frontend developers who don’t build backend services — and considering the rise of frameworks such as JAMStack and serverless that enable you to build applications without an actual API server — Okta provides a great way to implement authentication in your React applications without undue complexity.

Full visibility into production React apps

Debugging React applications can be difficult, especially when users experience issues that are hard to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket. LogRocket Dashboard Free Trial Banner

LogRocket is like a DVR for web apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.

The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

Modernize how you debug your React apps — start monitoring for free.

Sours: https://blog.logrocket.com/implementing-okta-authentication-react-app/


1736 1737 1738 1739 1740