1

I am using react-router-dom v6. Trying to authenticate user using oidc client and if authenticated the Private page should allow. However I am getting this error below. I am not sure what I am doing wrong. appreciate your inputs on this please.

Uncaught Error: A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in

a . at invariant (history.ts:480:1) at Route (components.tsx:274:1) at renderWithHooks (react-dom.development.js:16305:1) at mountIndeterminateComponent (react-dom.development.js:20074:1) at beginWork (react-dom.development.js:21587:1) at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1) at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1) at invokeGuardedCallback (react-dom.development.js:4277:1) at beginWork$1 (react-dom.development.js:27451:1) at performUnitOfWork (react-dom.development.js:26557:1)

The above error occurred in the <Route> component:

    at Route (http://localhost:3000/static/js/bundle.js:48027:78)
    at PrivateRoute (http://localhost:3000/static/js/bundle.js:426:14)
    at RenderedRoute (http://localhost:3000/static/js/bundle.js:47638:5)
    at Routes (http://localhost:3000/static/js/bundle.js:48103:5)
    at AuthProvider (http://localhost:3000/static/js/bundle.js:193:5)
    at Router (http://localhost:3000/static/js/bundle.js:48041:15)
    at BrowserRouter (http://localhost:3000/static/js/bundle.js:46238:5)
    at App

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render( <App /> );

App.js

import React from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import PrivateRoute from './PrivateRoute';
import HomePage from './HomePage';
import Profile from './Profile';
import Login from './Login';
import {AuthProvider} from "./AuthProvider";

function App() {
  return (
    <Router>
      <AuthProvider>
        <Routes>
          <Route exact path="/signin-oidc" element={<HomePage />} />
          <Route
            exact
            path="/profile"
            element={<PrivateRoute><Profile /></PrivateRoute>}
          />
          <Route exact path="/" element={<HomePage /> } />
          <Route exact path="/login" element={<Login />} />
        </Routes>
      </AuthProvider>
    </Router>
  );
}
export default App;

HomePage.js

export default function HomePage() {
  return (
    <div>home page</div>
  )
}

Profile.js

export default function Profile() {
  return (
    <div>profile page</div>
  )
}

Login.js

export default function Login() {
  return (
    <div>login page</div>
  )
}

PrivateRoute.js

import React from "react";
import { Route, Navigate } from "react-router-dom";
import { useAuth } from "./AuthProvider";

export default function PrivateRoute({ element: Component, ...rest }) {
  const { isAuthenticated } = useAuth();

  return (
    <Route
      {...rest}
      element={isAuthenticated
        ? (<Component />)
        : (<Navigate to="/login" replace />)
      }
    />
  );
}

AuthProvider.js

import React, { createContext, useContext, useEffect, useState } from "react";
import { UserManager } from "oidc-client";

export const oidcConfig = {
  authority: 'https://idp.myid.abcdef.com/.well-known/openid-configuration',
  client_id: 'oidc-client-20230304-0001',
  redirect_uri: 'http://localhost:3000/signin-oidc',
  response_type: 'id_token token',
  automaticSilentRenew: true,
  loadUserInfo: true,
  scope: 'openid profile email',
};

const userManager = new UserManager({ ...oidcConfig });

const AuthContext = createContext();

export function AuthProvider({ children }) {
  const [isAuthenticated, setIsAuthenticated] = useState(false);
  const [user, setUser] = useState(null);

  useEffect(() => {
    const loadUserFromStorage = async () => {
      const user = await userManager.getUser();
      if (user) {
        setIsAuthenticated(true);
        setUser(user);
      }
      console.log(user)
    };

    loadUserFromStorage();
  }, []);

  const login = async () => {
    console.log("in signin-redirect")
    await userManager.signinRedirect();
  };

  const logout = async () => {
    await userManager.signoutRedirect();
  };

  return (
    <AuthContext.Provider
      value={{ isAuthenticated, user, login, logout }}
    >
      {children}
    </AuthContext.Provider>
  );
}

export function useAuth() {
  return useContext(AuthContext);
}
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
Prakash Raj
  • 149
  • 3
  • 13

0 Answers0