This is the companion blog post for a video I have on using AWS Amplify for Authentication in a Remix Application.
We show how to implement complete authentication flows to your application with minimal boilerplate. We then make a database query using the AWS Appsync API with GraphQL to retrieve data.
This video does not walkthrough setting up an AWS Amplify environment, there are plenty of videos cover that already, this just shows how to using Remix within your preconfigured environment
Setup
In Root.tsx we configure Amplify and set up the provider so we can use the hooks later to get information about the authenticated user/
In routes/index.jsx we check in the LoaderFunction to see if we have a valid session. If we do not have a valid session then we redirect to the login route, otherwise we redirect to the task page.
The requireUserId takes a redirectTo parameter which in this case is /login and throws and exception with a redirect which causes the route to change
// routes/index.jsximport{redirect}from"@remix-run/node";import{requireUserId}from"~/session.server";/**
* check for authenticated user, if not redirect to
* login
*
* @param {*} param0
* @returns
*/exportasyncfunctionloader({request}){constid=awaitrequireUserId(request,"/login");returnredirect("/tasks");}
Authentication Flow
On the routes/login.jsx page is where a lot of the activity happens, In this page we are just rendering the AWS Amplify Authenticator UI Component and it manages the login and create account functionality for us.
Once the login is complete, we use the user returned from the useAuthenticator hook to get the current user which is then passed to the server through the function setUserSessionInfo which sets some form data with the parameters and uses fetcher to call the routes ActionFunction.
// routes/login.jsxexportfunctionLogin(){// for calling actionconstfetcher=useFetcher();const{user}=useAuthenticator((context)=>[context.user]);useEffect(()=>{console.log(user);setUserSessionInfo(user);},[user]);/**
*
*/constsetUserSessionInfo=useCallback((user)=>{// if i have a user then submit the tokens to the// action function to set up the cookies for server// authenticationif (user&&fetcher.type==="init"){fetcher.submit({accessToken:user?.signInUserSession?.accessToken?.jwtToken,idToken:user?.signInUserSession?.idToken?.jwtToken,},{method:"post"});}},[user]);
Finally the setUserSessionInfo function calls the action; you can see in the action below we call our function to set the cookie session using the information provided to us from Amplify.
// login.jsx/**
*
*/exportconstaction:ActionFunction=async ({request})=>{// get data from the formletformData=awaitrequest.formData();letaccessToken=formData.get("accessToken");letidToken=formData.get("idToken");// create the user sessionreturnawaitcreateUserSession({request,userInfo:{accessToken,idToken,},redirectTo:"/tasks",});};
This is the function createUserSession in session.server.ts where we use the cookie package provided to us by Remix to save the session information so we can retrieve it later to confirm we have an authenticated user.
Next we create an AWSAppSyncClient that we can use to query from the databased using graphql. The important thing to note is that we are using the accessToken from the session cookie to make the authenticated API call.
all of the config props come the the aws-exports.js file
The only action in this component is to logout of the application. Here we call another function from session.server to log us out and clean up the cookies.
Working with Remix: AWS Amplify Authentication Using Authenticator UI and AppSync Integration
code sample of integrating AWS Amplify with a Remix Application. We show how to implement complete authentication flows to your application with minimal boilerplate. We then make a database query using the AWS Appsync API to retrieve data.