Applications without user authentication cannot reliably store and present data tied to a specific user. And users expect the ability to save data, close the app, and return to the app and interact with the same data they created. To do this securely (in a way that doesn’t allow anyone to access anyone else’s data), you need to support authentication. The most common approach to this is a username/password pair.
However, the user doesn’t want to submit their password every time they need to make a request for data. They want to be able to log into the application and then the application can continuously authenticate requests for them automatically. That said, we don’t want to store the user’s password and send that with every request. A common solution to this problem is to use a special limited use “token” which represents the user’s current session. That way the token can be invalidated (in the case that it’s lost or stolen) and the user doesn’t have to change their password. They simply re-authenticate and they can get a fresh token.
So, every request the client makes must include this token to make authenticated
requests. This is one reason it’s so nice to have a small wrapper around
window.fetch
: so you can automatically include this token in every request
that’s made. A common way to attach the token is to use a special request header
called “Authorization”.
Here’s an example of how to make an authenticated request:
window.fetch('http://example.com/pets', {headers: {Authorization: `Bearer ${token}`,},})
That token can really be anything that uniquely identifies the user, but a common standard is to use a JSON Web Token (JWT). 📜 https://jwt.io
Authentication and user identity management is a difficult problem, so it’s recommended to use a service to handle this for you. Most services will give you a mechanism for retrieving a token when the user opens your application and you can use that token to make authenticated requests to your backend. Some services you might consider investigating are Auth0, Netlify Identity, and Firebase Authentication.
Regardless of what service provider you use (or if you build your own), the things you’ll learn in this exercise are the same:
const token = await authProvider.getToken()const headers = {Authorization: token ? `Bearer ${token}` : undefined,}window.fetch('http://example.com/pets', {headers})
In a React application you manage user authenticated state the same way you
manage any state: useState
+ useEffect
(for making the request). When the
user provides a username and password, you make a request and if the request is
successful, you can then use that token to make additional authenticated
requests. Often, in addition to the token, the server will also respond with the
user’s information which you can store in state and use it to display the user’s
data.
The easiest way to manage displaying the right content to the user based on whether they’ve logged in, is to split your app into two parts: Authenticated, and Unauthenticated. Then you choose which to render based on whether you have the user’s information.
And when the app loads in the first place, you’ll call your auth provider’s API to retrieve a token if the user is already logged in. If they are, then you can show a loading screen while you request the user’s data before rendering anything else. If they aren’t, then you know you can render the login screen right away.
📜 Learn more about this: https://kentcdodds.com/blog/authentication-in-react-applications
Quick Links
Legal Stuff
Social Media