- 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.js
page for a/auth
route- in
App.js
, add a new route definition for thisauth
route - 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 theto
attribute set to?mode
& a value based on the currently selected mode - manage your
mode
with query parameters & access the currently set query parameter with theuseSearchParams
hook
- update
MainNavigation.js
so that when we clickAuthentication
we load this login form by default
- enable user creation with an
action
- in
Authentication.js
, add anaction
that is triggered when theForm
inAuthForm.js
is submitted - get the data from the form with
formData
- send different requests based on the
mode
this 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 theaction
data with theuseActionData
hook - your
action
function must return something and not only aredirect
- in our case it returns a
response
in 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
useNavigation
hook
- The login feature already works because the
action
we created inAuthentication.js
send 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
localStorage
after signing up or loging in - in a new
util
folder, add a newauth.js
file where you add a helpergetAuthToken
function to get that storedtoken
when needed - use that
getAuthToken
function inEventDetail.js
for deleting events & inEventForm.js
for adding and editing events
- in
MainNavigation.js
, add a newlogout
navigation link - the button should trigger an
action
that deletes the token- add a new
Logout.js
pages in thepages
folder - inside of it define an
action
that clears thelocalStorage
& gets rid of thetoken
- add a new
- in
App.js
, register a newlogout
route - 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
token
easily available in your entire app (on all your routes basically) - the information whether the
token
is available or not should be automatically updated so that the UI automatically updates
- make the
- to do so, you could use the
useContext
hook - but, leverage React Router for doing that
- in
App.js
, in the root route, add aloader
that takes a look atlocalStorage
& extract thetoken
from it - React Router will reevaluate that, if we, for example, logout & update all the pages that use that
loader
data - in
util/auth.js
, add thetokenLoader
function & callgetAuthToken()
inside of it & return its result - in order to use the data from that
tokenLoader
& easily get access to it, assign anid
with a value ofroot
to that route - in
MainNavigation.js
, use theuseRouteLoaderData
hook to get thetoken
by targetting theroot
id - conditionally show that
Authentication
link if thetoken
doesn't exist (so when the user is not logged in) - show the
Logout
link only when thetoken
(so when the user is logged in) - in
EventsNavigation.js
, use the same approach as inMainNavigation.js
& show theNew Event
link if there is atoken
- in
EventItem.js
, do the same to conditionally show theEdit
&Delete
menu
- 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
&new
routes so that there will not be accessible unless the user is logged in- in
util/auth.js
, add acheckAuthLoader
function that checks if there is atoken
& if not redirects the user away - in
App.js
, use thischeckAuthLoader
to protect all these routes that need protection
- in
- in
Root.js
, useuseEffect()
to set a timer whenever theRootLayout
is rendered which happens when this application starts - use
useLoaderData()
to get thetoken
- use this
token
as a dependency foruseEffect
so that this effect function runs whenever thetoken
changes - set a timer that expires after 1 hour & that then triggers that logout action (basically sends a request to that
logout
route) - for that, use the
useSubmit()
hook to programmatically submit thatlogout
form 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 thisexpiration
date & find out if the token expired with help of a newgetTokenDuration()
function - in
Root.js
, trigger thelogout
action, 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 theexpiration
from thelocalStorage