- How Authentication Works in React Apps
- Implementing User Authentication
- Adding Authentication Persistence & Auto-Logout
- run
cd backend/&npm install&npm start - run
cd frontend/&npm install&npm start - set a way to go to the
Authentication.jspage for a/authroute- in
App.js, add a new route definition for thisauthroute - in
MainNavigation.js, add an entry to the main navigation to navigate to the authentication page
- in
- leverage query parameters in
AuthForm.js- get rid of the state
- replace the button with a
<Link>& add to it thetoattribute set to?mode& a value based on the currently selected mode - manage your
modewith query parameters & access the currently set query parameter with theuseSearchParamshook
- update
MainNavigation.jsso that when we clickAuthenticationwe load this login form by default
- enable user creation with an
action- in
Authentication.js, add anactionthat is triggered when theForminAuthForm.jsis submitted - get the data from the form with
formData - send different requests based on the
modethis form is in with help ofsearchParams - send the request to the backend
- handle the response
- in
- in
App.js, add this action to the route definitions
- in
AuthForm.js, get theactiondata with theuseActionDatahook - your
actionfunction must return something and not only aredirect - in our case it returns a
responsein case of 422 or 401 errors inAuthentication.js - output that information to the user in
AuthForm.js - add an indicator that the form was submitted successfully & that we're waiting for the response with the
useNavigationhook
- The login feature already works because the
actionwe created inAuthentication.jssend a request based on the selected mode - in
Authentication.js, attach the token we're getting back from the backend to requests to protect resources because now if you try to delete an event, you get an 401 unauthorized error- extract from the backend
- store that token in
localStorageafter signing up or loging in - in a new
utilfolder, add a newauth.jsfile where you add a helpergetAuthTokenfunction to get that storedtokenwhen needed - use that
getAuthTokenfunction inEventDetail.jsfor deleting events & inEventForm.jsfor adding and editing events
- in
MainNavigation.js, add a newlogoutnavigation link - the button should trigger an
actionthat deletes the token- add a new
Logout.jspages in thepagesfolder - inside of it define an
actionthat clears thelocalStorage& gets rid of thetoken
- add a new
- in
App.js, register a newlogoutroute - in
MainNavigation.js, send a request to this route by submitting a<Form>that targets this route
- update the UI based on the existence of the
token- make the
tokeneasily available in your entire app (on all your routes basically) - the information whether the
tokenis available or not should be automatically updated so that the UI automatically updates
- make the
- to do so, you could use the
useContexthook - but, leverage React Router for doing that
- in
App.js, in the root route, add aloaderthat takes a look atlocalStorage& extract thetokenfrom it - React Router will reevaluate that, if we, for example, logout & update all the pages that use that
loaderdata - in
util/auth.js, add thetokenLoaderfunction & callgetAuthToken()inside of it & return its result - in order to use the data from that
tokenLoader& easily get access to it, assign anidwith a value ofrootto that route - in
MainNavigation.js, use theuseRouteLoaderDatahook to get thetokenby targetting therootid - conditionally show that
Authenticationlink if thetokendoesn't exist (so when the user is not logged in) - show the
Logoutlink only when thetoken(so when the user is logged in) - in
EventsNavigation.js, use the same approach as inMainNavigation.js& show theNew Eventlink if there is atoken - in
EventItem.js, do the same to conditionally show theEdit&Deletemenu
- in
- the user can still access a specific page that needs a token directly in the URL, like
/events/new - in
App.js, protect theedit&newroutes so that there will not be accessible unless the user is logged in- in
util/auth.js, add acheckAuthLoaderfunction that checks if there is atoken& if not redirects the user away - in
App.js, use thischeckAuthLoaderto protect all these routes that need protection
- in
- in
Root.js, useuseEffect()to set a timer whenever theRootLayoutis rendered which happens when this application starts - use
useLoaderData()to get thetoken - use this
tokenas a dependency foruseEffectso that this effect function runs whenever thetokenchanges - set a timer that expires after 1 hour & that then triggers that logout action (basically sends a request to that
logoutroute) - for that, use the
useSubmit()hook to programmatically submit thatlogoutform fromMainNavigation.js
- in
Authentication.js, where you store the token, store the expiration time with help ofDate()etsetHours() - in
util/auth.js, update thegetAuthToken()function to take a look at thisexpirationdate & find out if the token expired with help of a newgetTokenDuration()function - in
Root.js, trigger thelogoutaction, if the token duration expired - if the token is not expired, set the timeout duration at the remaining lifetime of the token
- in
Logout.js, remove theexpirationfrom thelocalStorage