Use MSW to Mock Authentication in Remix

Share this video with your friends

Social Share Links

Send Tweet
Published 7 months ago
Updated 6 months ago

Mocking authentication comes down to how it's implemented. With Mock Service Worker, you can mock the "Set-Cookie" response header to emulate a user session, but with Remix you don't even have to. Instead, in this lesson we will intercept only the authorization call to a database, leaving Remix to handle sessions, cookies, and auth state for us.

Lecturer: [0:04] Describing authentication will largely depend on the way you decide to implement it and will vary from simple JSON responses to mocking the entire request flow, auth tokens, and response cookies. No matter the approach, you can always represent it with MSW.

[0:15] In our application, we have a signing route that renders the authentication form on the client and has a server action to handle form submissions. We will follow Remix's best practices and create, store, and invalidate the user session using cookies. Let's take a closer look at this authentication flow.

[0:32] First, we get the credentials that the user submitted as the requests form data, then we forward them to a third-party endpoint for validation. You can think of this request as a call to the auth provider or a direct REST API call to your database to see if the user exists. If it does, we take the user object returned from the validation response and set it on our session.

[1:00] After we've handled errors, we set the session cookie on the response and finish the flow. In a setup like this, controlling authentication comes down to controlling the validation request, so let's do that with MSW. In our handlers, create a new HTTP post handler for the validation endpoint.

[1:16] We are forwarding the request's form data body from the Remix action to this request so we can get the submitted user credentials by reading the intercepted request body as request.formData. Let's grab the user's email and password using the form data's GET method. Next, add the basic input validation to respond with a 400 response if any of the credentials are missing.

[1:49] Finally, send a response to indicate a successful authentication. This response will depend on what the client expects from this endpoint, which in our case is the user object.

[2:00] Now, the validation endpoint will always return this user object and proceed to store it in the cookies, creating a new session once we sign in with any credentials. Since the sign-out route invalidates any present session cookies using Remix, we get the sign-out functionality out of the box, no handlers necessary.

~ 6 months ago

This part doesn't work for me, even in the "completed" branch. I get this error:

Application Error

TypeError: Secret key must be provided. at Object.exports.sign (/Users/valla/Projects/msw-movie-app/node_modules/cookie-signature/index.js:18:29) at sign (/Users/valla/Projects/msw-movie-app/node_modules/@remix-run/node/dist/crypto.js:22:46) at encodeCookieValue (/Users/valla/Projects/msw-movie-app/node_modules/@remix-run/server-runtime/dist/cookies.js:85:21) at Object.serialize (/Users/valla/Projects/msw-movie-app/node_modules/@remix-run/server-runtime/dist/cookies.js:67:63) at commitSession (/Users/valla/Projects/msw-movie-app/node_modules/@remix-run/server-runtime/dist/sessions/cookieStorage.js:39:43) at action2 (/Users/valla/Projects/msw-movie-app/app/routes/_grid.sign-in.tsx:53:27) at processTicksAndRejections (node:internal/process/task_queues:95:5) at Object.callRouteActionRR (/Users/valla/Projects/msw-movie-app/node_modules/@remix-run/server-runtime/dist/data.js:35:16) at callLoaderOrAction (/Users/valla/Projects/msw-movie-app/node_modules/@remix-run/router/router.ts:3688:16) at submit (/Users/valla/Projects/msw-movie-app/node_modules/@remix-run/router/router.ts:2833:16)

~ 6 months ago

Same error for me!

Artem Zakharchenko
Artem Zakharchenkoinstructor
~ 6 months ago

Hi, folks! Thanks for pointing that out.

The error was caused by Remix missing the value in the "secrets" key in "app/session.ts" to sign the authentication cookie. That secret was loaded from the ".env" file, which is normally ignored in Git, so you didn't have it and got the error because it was missing.

For the sake of the exercises, I've committed the ".env" file to Git so if you rebase the repo now, you will get a dummy secret value and the error will be gone. Please note that in real applications, you MUST NEVER commit ".env" files to Git.

Markdown supported.
Become a member to join the discussionEnroll Today