You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
set a way to go to the Authentication.js page for a /auth route
in App.js, add a new route definition for this auth route
in MainNavigation.js, add an entry to the main navigation to navigate to the authentication page
1. Working with Query Parameters
leverage query parameters in AuthForm.js
get rid of the state
replace the button with a <Link> & add to it the to 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 the useSearchParams hook
update MainNavigation.js so that when we click Authentication we load this login form by default
2. Implementing the Auth Action
enable user creation with an action
in Authentication.js, add an action that is triggered when the Form in AuthForm.js is submitted
get the data from the form with formData
send different requests based on the mode this form is in with help of searchParams
send the request to the backend
handle the response
in App.js, add this action to the route definitions
3. Validating User Input & Outputting Validation Errors
in AuthForm.js, get the action data with the useActionData hook
your action function must return something and not only a redirect
in our case it returns a response in case of 422 or 401 errors in Authentication.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
4. Attaching Auth Tokens to Outgoing Requests
The login feature already works because the action we created in Authentication.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 new auth.js file where you add a helper getAuthToken function to get that stored token when needed
use that getAuthToken function in EventDetail.js for deleting events & in EventForm.js for adding and editing events
5. Adding User Logout
in MainNavigation.js, add a new logout navigation link
the button should trigger an action that deletes the token
add a new Logout.js pages in the pages folder
inside of it define an action that clears the localStorage & gets rid of the token
in App.js, register a new logout route
in MainNavigation.js, send a request to this route by submitting a <Form> that targets this route
6. Updating the UI Based on Auth Status
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
to do so, you could use the useContext hook
but, leverage React Router for doing that
in App.js, in the root route, add a loader that takes a look at localStorage & extract the token 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 the tokenLoader function & call getAuthToken() inside of it & return its result
in order to use the data from that tokenLoader & easily get access to it, assign an id with a value of root to that route
in MainNavigation.js, use the useRouteLoaderData hook to get the token by targetting the root id
conditionally show that Authentication link if the token doesn't exist (so when the user is not logged in)
show the Logout link only when the token (so when the user is logged in)
in EventsNavigation.js, use the same approach as in MainNavigation.js & show the New Event link if there is a token
in EventItem.js, do the same to conditionally show the Edit & Delete menu
7. Adding Route Protection
the user can still access a specific page that needs a token directly in the URL, like /events/new
in App.js, protect the edit & new routes so that there will not be accessible unless the user is logged in
in util/auth.js, add a checkAuthLoader function that checks if there is a token & if not redirects the user away
in App.js, use this checkAuthLoader to protect all these routes that need protection
8. Adding Automatic Logout
in Root.js, use useEffect() to set a timer whenever the RootLayout is rendered which happens when this application starts
use useLoaderData() to get the token
use this token as a dependency for useEffect so that this effect function runs whenever the token 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 that logout form from MainNavigation.js
9. Managing the Token Expiration
in Authentication.js, where you store the token, store the expiration time with help of Date() et setHours()
in util/auth.js, update the getAuthToken() function to take a look at this expiration date & find out if the token expired with help of a new getTokenDuration() function
in Root.js, trigger the logout 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 the expiration from the localStorage
About
This demo app enhances my previous React Router Events project with user authentication. 🗝️ It includes toggleable login and signup forms, 🛡️ maintains user login status, ⏱️ features auto-logout, and 🚧 protects certain routes for logged-in users only. The UI updates based on the user's authentication status.