Start learning free

LESSON 21 OF 58 · FULL-STACK: LOGIN WITH COOKIES

Pages That Need a Login

Practice

The server already refuses GET /api/orders without a login: it answers 401. But the storefront still draws the Orders page for everybody, so a visitor who isn't logged in gets an empty list and "Login required", with no way forward. A guard component fixes that: it wraps a page and decides, before the page renders, whether to show it.

In App.jsx (given), RequireUser wraps OrdersPage. Whatever sits between a component's tags reaches it as children, so returning children shows the page. To send the visitor somewhere else, a component returns React Router's <Navigate>. For example, a login page could send a visitor who is already logged in back home:

if (user) {
  return <Navigate to="/" replace />;
}

replace swaps the current address instead of adding one, so the Back button doesn't lead to a page that sends you away again. The login page (given) reads next from its address, as in /login?next=/orders, and goes there after the login. One catch: right after a reload, user is null until /api/me answers, even for a visitor who is logged in. While loading is true, the guard must wait.

The check opens /orders logged out, logs in as Ana, then reloads the page:

> open /orders
  screen while waiting: text: Loading…
  answer: GET /api/me -> 401
  address bar: /login?next=/orders
> log in as ana@example.com
  request: GET /api/orders -> 200
  address bar: /orders
> reload the page
  screen while waiting: text: Loading…
  answer: GET /api/me -> 200
  address bar: /orders

Your task: in client/src/RequireUser.jsx, show "Loading…" while /api/me hasn't answered, send a visitor without a user to /login?next= plus the page's path (replacing the address), and otherwise show the children.


Assignment
Follow the Coding Tutorial to finish RequireUser: take user and loading from useAuth() and the path from useLocation(), then return a <Navigate> or a Loading… paragraph when the page can't show yet.


Hint
Check loading before user: while /api/me is on its way, user is null for everybody. On this page, location.pathname is "/orders".


STEP 1 OF 6
    Ctrl + Enter to check