CORS No 'Access-Control-Allow-Origin in Okta SignInWidget

Viewed 1013

I am incorporating Okta into my React application. I created a Login page with the SignInWidget and it actually looks like the POST request sent with the login data is sending correctly with status 200 to 'https://{oktaDomain}/api/v1/authn. However, immediately following this request is GET request from {oktaDomain}/oath2/default/.well-known/openid-configuration with the following error message:

Access to XMLHttpRequest at 'https://{domain}.okta.com/oath2/default/.well-known/openid-configuration' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

From similar questions on here, the only answer I can find is to ensure that localhost:3000 is accepted as a trusted source within Okta API and it is. I also get the following errors in the console immediately afterward:

enter image description here

Here is my code for the SignInWidget:

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';
import appConfig from '../../app.config';

export default class OktaSignInWidget extends Component {
    componentDidMount() {
        const el = ReactDOM.findDOMNode(this);
        this.widget = new OktaSignIn({
            baseUrl: this.props.baseUrl,
            el: '#widget',
            authParams: {
                pkce: true,
                issuer: appConfig.issuer
            }
        });
        
        this.widget.renderEl({el}, this.props.onSuccess, this.props.onError);
    }

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

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

Here is the code for the Login Page:

import React, {Component} from 'react'
import { Redirect } from 'react-router-dom';
import OktaSignInWidget from './OktaSignInWidget';
import withOktaAuth from '@okta/okta-react/dist/withOktaAuth';
import Navbar from '../Navbar/Navbar';
import Footer from '../Footer/Footer'

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

            this.checkAuthentication();
        }


        checkAuthentication = async () => {
            const authenticated = this.props.authState.isAuthenticated;
            if (authenticated !== this.state.authenticated) {
                this.setState({authenticated})
            }
        }

        componentDidUpdate() {
            this.checkAuthentication();
        };

        onSuccess = (res) => {
            if (res.status === 'SUCCESS') {
                return this.props.authService.redirect({
                    sessionToken: res.session.token
                });
            }
        }

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

        render() {
            return this.state.authenticated ?
                <Redirect to={{pathname: '/'}} /> :
                <div className="login">
                    <Navbar />
                    <OktaSignInWidget
                        baseUrl={this.props.baseUrl}
                        onSuccess={this.onSuccess}
                        onError={this.onError}/> 
                    <Footer />                   
                </div>

        }
    }
)

Here is the App

...
import { Route, Switch, withRouter } from 'react-router-dom';
import LoginCallback from '@okta/okta-react/dist/LoginCallback';
import SecureRoute from '@okta/okta-react/dist/SecureRoute';
import ProfilePage from './Components/ProfilePage';
import Security from '@okta/okta-react/dist/Security';
import appConfig from './app.config';
import Login from './Components/BusinessAuth/Login';



class App extends Component {
  constructor(props) {
    super(props)
  
    this.state = {
       
    }
  }

  onAuthRequired = () => {
    this.props.history.push('/login');
  }
  
  render() {
      return (
        <div>
          <Security
            issuer={appConfig.issuer}
            client_id={appConfig.client_id}
            redirect_uri={appConfig.redirect_uri}
            onAuthRequired={this.onAuthRequired}
            pkce={true}
          >
            <Switch>
                ...
                <Route path='/login' render={() => <Login baseUrl={appConfig.url} />}  />
                <Route component={LoginCallback} path='/implicit/callback'  />
                <SecureRoute component={ProfilePage} path='/profile' />
                <Route component={LandingPage} path='/' />
            </Switch>
          </Security>
        </div>
      );
    }    
  }


export default withRouter(App);

What are these errors and how can I correct them? Given that CORS should already be accepted from localhost:3000, I cannot figure out why the initial POST request seems to work but the GET request assigning a session token is not working.

1 Answers

You should configure the server to accept requests from a particular origin. It is just a pre-flight request that is sent by browsers to check if the server allows the specific origin to be served. For debugging purposes, you can use the cors-everywhere prefix. This is an intermediate server which makes request on our behalf and sets appropriate headers so that our browser can accept it.

Let us say your URL is

https://{domain}.okta.com/oath2/default/.well-known/openid-configuration,

just prefix it with

https://cors-anywhere.herokuapp.com/

like

https://cors-anywhere.herokuapp.com/https://{domain}.okta.com/oath2/default/.well-known/openid-configuration

and then make your request.

Related