Skip to content
This repository has been archived by the owner on Oct 24, 2024. It is now read-only.

Showing component only for authenticated user, but for every path, without rerendering each time path changes. #932

Open
2 of 8 tasks
adammo94 opened this issue Oct 21, 2020 · 5 comments

Comments

@adammo94
Copy link

I'm submitting this issue for the package(s):

  • jwt-verifier
  • okta-angular
  • oidc-middleware
  • okta-react
  • okta-react-native

I'm submitting a:

  • Bug report
  • Feature request
  • Other (Describe below)

Current behavior

So currently when I enter any unsecured route it reroutes to /login, I know this is happening due to SecureRoute path="/" with ScreensMain component not having 'exact' prop.

Expected behavior

My ScreensMain component contains navbar and topbar of my application and I would like it to be accessible for logged in users only, but also I DO NOT WANT it to rerender each time path changes.

Minimal reproduction of the problem with instructions

Extra information about the use case/user story you are trying to implement

My code:

<Security {...config} onAuthRequired={onAuthRequired}>
   <Route path={CALLBACK_PATH} component={LoginCallback} />
   <Route exact path="/login" render={() => <ScreensLogin issuer={config.issuer} />}/>
   <Route exact={true} path="/signup" component={() => <ScreensSignup />} />
   <SecureRoute path="/" component={() => <ScreensMain />} />
   <SecureRoute exact path="/" component={() => <ScreensDesktop />} />
   <SecureRoute exact path="/groups" component={() => <ScreensGroups />} />
   <SecureRoute exact path="/sensors" component={() => <ScreensSensors />} />
   <SecureRoute exact path="/contact" component={() => <ScreensContact />} />
</Security>

Environment

  • Package Version: 3.0.8
  • Browser: Chrome 85
  • OS: Windows 10
  • Node version (node -v): v12.19.0
  • Other:
@aarongranick-okta
Copy link
Contributor

@adammo94 Try using the render attribute on the route instead of component, the behavior is described here: https://reactrouter.com/web/api/Route

@adammo94
Copy link
Author

@adammo94 Try using the render attribute on the route instead of component, the behavior is described here: https://reactrouter.com/web/api/Route

Ok, but still I do not know how to make component to show for all paths when logged in, without rerouting to "/login" (onAuthRequired does this) when not logged in.

@aarongranick-okta
Copy link
Contributor

@adammo94 OK, I think I understand. You would like to have some UI that shows on all secured routes, but does not show on unsecured routes. The way it is defined here will cause problems because the component will also render on unsecured routes. This will probably break the callback route, which must be unsecured.

In this case, I think it would be better to render the header UI based on the auth state, without using a route definition. Remove the route definition for "/" and put your ScreensMain component inside another wrapper component that will render on all routes, perhaps as a child of your main Application component. Then you can use either useOktaAuth (for function based components) or withOktaAuth (for class based components) to only render ScreensMain when isAuthenticated is true. https://github.com/okta/okta-react#show-login-and-logout-buttons-function-based

@adammo94
Copy link
Author

@adammo94 OK, I think I understand. You would like to have some UI that shows on all secured routes, but does not show on unsecured routes. The way it is defined here will cause problems because the component will also render on unsecured routes. This will probably break the callback route, which must be unsecured.

In this case, I think it would be better to render the header UI based on the auth state, without using a route definition. Remove the route definition for "/" and put your ScreensMain component inside another wrapper component that will render on all routes, perhaps as a child of your main Application component. Then you can use either useOktaAuth (for function based components) or withOktaAuth (for class based components) to only render ScreensMain when isAuthenticated is true. https://github.com/okta/okta-react#show-login-and-logout-buttons-function-based

I tried code below (ScreensMain already checks for authState) and then two bad things happen:

  1. It reroutes me to login on every path
  2. It won't trigger onAuthRequired, so my custom login page is being skipped and it goes straight to okta
<Security {...config} onAuthRequired={onAuthRequired}>
            <ScreensMain>
              <Route path={CALLBACK_PATH} component={LoginCallback} />
              <Route exact path="/login" render={() => <ScreensLogin issuer={config.issuer} />}/>
              <Route exact={true} path="/signup" render={() => <ScreensSignup />} />
              <SecureRoute exact path="/" component={() => <ScreensDesktop />} />
              <SecureRoute exact path="/groups" component={() => <ScreensGroups />} />
              <SecureRoute exact path="/sensors" component={() => <ScreensSensors />} />
              <SecureRoute exact path="/contact" component={() => <ScreensContact />} />
            </ScreensMain>
          </Security>

@aarongranick-okta
Copy link
Contributor

@adammo94 Several routes, including "/" have plain attribute exact. I think it needs to be exact={true}. Also I do not think you want all your routes as children of <ScreensMain but as siblings:

<Security>
  <ScreensMain />
  <Route....
</Security>

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants