Core Auth Workflows with WeWeb and Xano

If you, like me, cannot stand videos as a medium for communicating code or technical walkthroughs, here is how to implement core auth workflows in WeWeb with Xano as your backend. I even put things in plain text so that you can copy and paste them as needed.

📣
New to WeWeb or Xano? Sign up using my WeWeb referral link and/or my Xano referral link and you'll get a 10% discount as well as my appreciation.

Prerequisites and Assumptions

In addition to Xano and WeWeb, you will require an email delivery provider that may or may not be SendGrid.

I will be providing assisted configuration instructions for the "MagicLink with SendGrid" extension that can be found on the Xano Marketplace. It has been documented here: https://www.xano.com/learn/Magic-Link-Passwordless-App-Authentication/

  1. You do not need SendGrid to use this. If you have SendGrid, awesome, this almost works out of the box. If you do not, this guide will cover where you will need to change references to SendGrid to those of your email delivery platform.
  2. The extension will create a new user table that contains the necessary magic_link field. If you already have a user table, you will now have two. Xano also does not support changing tables referenced in actions, so you will need to manually duplicate the actions to use your user table and remove the original actions. This guide will cover what needs to happen here.
  3. This guide assumes you already created a user table because I started implementing auth before I realised there wasn't a simple way to set up magic link without the extension. If you are coming at this with a completely clean database, install the extension first and you should be able to skip the bits where we fix what was described in the previous point.

Magic link support allows us to handle email verification and forgot password actions.

I would have liked to provide fully manual directions for setting up magic link support, but the way Xano is designed it's actually less of a nuisance to install the "MagicLink with SendGrid" extension and give directions for what needs to be remapped and cleaned up than to do it from scratch. If Xano provides a way to import/export blueprints for things more easily in future, I may revisit this guide. Until then:

Install the "MagicLink with SendGrid" extension from the Xano Marketplace.

This creates:

  • A second user table (if you have one already)
  • The auth/magic-login, auth/request-magic-link, generate_jwt_secret, and updated_password endpoints in a Password Reset API folder
  • The generate_jwt_secret, generate_magic_link, and sendgrid_dynamic_send functions under Library > Functions
  • The following environment variables found under Settings:
    • sendgrid_from_email
    • sendgrid_api_key
    • magic_link_redirect_uri
    • magic_jwt_secret
    • sendgrid_magic_link_template
    • magic_link_expiry_time
  1. Populate the sendgrid_ prefixed environment variables with your own values. If you don't use SendGrid you can still use the counterparts from the platform of your choice.
  2. We will not be using sendgrid_magic_link_template as we'll be modifying sendgrid_dynamic_send to allow us to pass the template name.
  3. magic_link_redirect_uri should contain your default magic link handling URL, eg. https://yourdomain.com/verify. It is used by generate_magic_link as the link prefix. Setup for this endpoint in WeWeb will be included in later in the guide.
  4. Go to Library > Functions and click on generate_jwt_secret and Run the function. Copy the generated secret from the response and paste it into the value for the magic_jwt_secret environment variable.

This is all we need here, but see the Xano documentation if you want more information about configuring and testing this extension.

Choose your own adventure

  1. Have the one user table that was created by the extension and use SendGrid? Skip down to WeWeb Xano Setup.
  2. Have the one user table that was created by the extension but don't use SendGrid? Do Update function SendGrid references and Update API endpoint SendGrid references then skip down to WeWeb Xano Setup.
  3. Had an existing user table so you now have two? Continue on. Once everything works the way you want it to, delete the second user table.

Bonus Content: I update the sendgrid_dynamic_send function to not use sendgrid_magic_link_template so that I can pass a custom template name in as a parameter so that I can also magic link supported password reset forms. If you want this functionality, make sure you take a look at Update function SendGrid references and Update API endpoint SendGrid references.

In Database, add a new json field to your existing user table called magic_link and set default to {}.

Update function user table references

In Library > Functions:

The generate_magic_link function has two references to the user table:

  • Get Record From user
  • Edit Record In user
ef45bf9d5088202d9556876292f1e51d_MD5.png
ef45bf9d5088202d9556876292f1e51d_MD5.png

If the extension created a second user table, these functions need to be manually duplicated to use your user table.

  1. Create a new Get Record function for the user table.
    Set the Filter for Find 'user' record by field to:
    • field_name = email (text)
    • field_value = email (input: email)
      Set Output Return as to user. Response can be left as default.
  2. Create a new Edit Record for the user table.
    Set the Filter Find 'user' record by field to:
    • field_name = id (text)
    • field_value = user.id (var: any)
      Set Output Return as to updated_magic_link. Customise Response to only return { magic_link: json }.
  3. Delete the original Get and Edit record functions.

Update function SendGrid references

In Library > Functions:

If you are not using SendGrid, the sendgrid_dynamic_send function needs to be modified for your email delivery provider. If you are using SendGrid and don't want customisable template names and don't need magic link supported password reset forms, you can skip this section.

I want to be able to use this function for any email sending so I changed the inputs to add flexibility. For example, I'm using Postmark and have set to_email, template_alias, and data (json) as my inputs. template_alias will allow me to send different templates for verifying email addresses, magic link supported passwordless authentication, and magic link supported password reset forms.

In the function stack, edit Makes an API request to Sendgrid to send an email through a template and replace the url with your provider's sending endpoint and update the params and headers as per your provider's documentation. I have also replaced the sendgrid_magic_link_template environment variable with the template_alias input so that I can customise the sending template to use.

ⓘ
If you need to pass a variable into a header, the values by default accept strings, so you will need to convert the value field into an expression and concatenate the header with the variable using a tilde (~). eg. 'X-Custom-Header: ' ~ $env.sendgrid_api_key

Update API endpoint user table references

The auth/magic-login endpoint has two references to the user table:

  • Get Record From user
  • Edit Record In user
dacdf30eef6a51c5fc3a88478ea6d55a_MD5.png
dacdf30eef6a51c5fc3a88478ea6d55a_MD5.png

These functions need to be manually duplicated to use your user table.

  1. Create a new Get Record function for the user table.
    Set the Filter for Find 'user' record by field to:
    • field_name = id (text)
    • field_value = decoded_magic_token (var: any)
      Add a get filter for path user_id (text), default null
      Set Output Return as to user. Response can be left as default.
  2. Create a new Edit Record for the user table.
    Set the Filter Find 'user' record by field to:
    • field_name = id (text)
    • field_value = user.id (var: any)
      Set Output Return as to user. Response can be left as default.
  3. Delete the original Get and Edit record functions.

The auth/update-password endpoint has two references to the user table:

  • Get Record From user
  • Edit Record In user
fa976b13921189d54883e16426de2f9c_MD5.png
fa976b13921189d54883e16426de2f9c_MD5.png

These function need to be manually duplicated to use your user table.

  1. Create a new Get Record function for the user table.
    Set the Filter for Find 'user' record by field to:
    • field_name = id (text)
    • field_value = id (auth)
      Add a get filter for path user_id (text), default null
      Set Output Return as to user. Response can be left as default.
  2. Create a new Edit Record for the user table.
    Set the Filter Find 'user' record by field to:
    • field_name = id (text)
    • field_value = id (auth)
      Set Output Return as to user. Response can be left as default.
  3. Delete the original Get and Edit record functions.

Update API endpoint SendGrid references

The auth/request-magic-link endpoint has an invocation for Custom Function sendgrid_dynamic_send that needs to be updated to reflect your changes to the function in Update function SendGrid references. Make sure the magic link returned by generate_magic_link is passed to your provider to be included in the templates.

This endpoint can be used for email verification and passwordless authentication, but if you also want to magic link supported password reset forms as well, clone the auth/request-magic-link endpoint to auth/reset-password and change your magic link url to point to your Reset Password page which will be set up later in the guide. In my case, passing the magic link as $var.magic_link|replace:"verify":"reset-password" will change a magic_link_redirect_uri of https://yourdomain.com/verify to https://yourdomain.com/reset-password.

WeWeb Xano Setup

In Xano, enable authentication on your user table (minimum required fields are email , password, and name). As per Xano documentation:

  1. Navigate to your database table (e.g., the "user" table) in the Xano interface.
  2. Click on the three-dot menu in the top-right corner and select "Settings."
  3. In the settings window, you'll find the "Authentication" option. Make sure it's enabled for the table you want to use for authentication purposes.
  4. Click "Save" to apply the changes.

Xano creates three endpoints for authentication purposes: auth/signup, auth/login, and auth/me.

In WeWeb, you will need to add the Xano plugin (under Data sources) and Xano Auth plugin (under Authentication). To configure both of these, you will need:

  • Metadata API key (found here)
  • Instance name
  • Instance domain
  • Workspace

The last three you can find by clicking on the workspace link at the top left of the Xano UI.

55758656aec452a04d09b76ec3370148_MD5.png
55758656aec452a04d09b76ec3370148_MD5.png

WeWeb Screens

Verify

This is needed to handle the magic link set in magic_link_redirect_uri.

  1. In WeWeb, create a verify page with the path /verify (or match your magic_link_redirect_uri). Add a simple 'Verifying…' text component.
  2. Add variables to allow you to toggle an error message, eg. verifyMessageShown (Boolean) and verifyMessage (Text) and bind them to a text component to display a message that you can toggle.
  3. Add a token variable of type Query to store the token from the magic link query params.
  4. From the Pages list, click the Verify settings cog to reveal the Verify page settings panel and click on Trigger Page Workflows.
  5. Create an On page load workflow that:
    1. Uses a True/False split to test if the token variable is set.
    2. Calls a Xano Request action named Validated token to auth/magic-login passing the token variable as magic_token.
    3. Calls a Xano Auth Store Auth Token action with Validate token.result.data.authToken.
    4. Calls a Xano Auth Fetch user action which will set the session in WeWeb.
    5. Navigates somewhere else like an auth-gated page.
    6. Will display an error if token isn't set or if the On Error workflow handler is invoked.

⚠︎
Calling Store Auth Token is not enough to set the session in WeWeb. Both Store Auth Token and Fetch user are required for the session to be set and usable.
3a512ea3e9842f8c1ae0ab17e7678144_MD5.png
3a512ea3e9842f8c1ae0ab17e7678144_MD5.png

Sign Up

  1. In WeWeb, create a signup page. Use the Xano Auth provided 'Sign up' UI block or create your own form.
  2. In the On submit Workflow for the form container, add or edit the Xano Auth 'Sign up' action and populate the body fields for the signup endpoint from the form fields. The defaults should be email, password, and name.
  3. The 'Sign up' action sets the session in WeWeb so the last action for this workflow can Navigate to an auth-gated page.
  4. Configure the On error workflow as needed. The Xano UI block contains variables and an error message element that you can toggle.

With email verification

In the Xano auth/signup endpoint, you will need to generate a magic link to pass to your email delivery provider. This is effectively a duplicate of the function stack for auth/request-magic-link with a different email template.

In the auth/signup function stack after the authToken is generated:

  1. Add the generate_magic_link Custom Function.
    Set the email input to email (input: email).
    Set Output Return as to magic_link.
  2. Add a Precondition function WHERE magic_link (var: any) != null.
    Set Error message to be Magic link could not be created. Try again..
    Set Error type to Standard.
    Leave Payload empty.
  3. Add the sendgrid_dynamic_send Custom Function.
    Map the INPUTS defined in Update function SendGrid references.
    Make sure you pass the generated magic_link to your template. This is what mine looks like for use with Postmark.
ecc00010177858ab52a39a98053edec4_MD5.png
ecc00010177858ab52a39a98053edec4_MD5.png

My welcome email template contains a welcome message to the user and a prompt to verify their email address with the action_url.

The resulting function stack will look something like this.
Note: I replaced all references to sendgrid with postmark.

35bfb04723a80d7f9c3a39b789e23316_MD5.png
35bfb04723a80d7f9c3a39b789e23316_MD5.png

When the user clicks on the verify link, it will send them to the Verify screen.

ⓘ
While in development, the full magic link may not resolve so you will need to copy the token from your email into the WeWeb variable to test it.

Login

  1. In WeWeb, create a login page. Use the Xano Auth provided 'Login' UI block or create your own form.
  2. In the On submit Workflow for the form container, add or edit the Xano Auth 'Login' action and populate the body fields for the endpoint from the form fields. The defaults should be email and password.
  3. The 'Login' action updates the session in the WeWeb front-end so the last action for this workflow can Navigate to an auth-gated page.
  4. Configure the On error workflow as needed. The Xano UI block contains variables and an error message element that you can toggle.

Logout

  1. In WeWeb, create a logout page. The UI can be left blank or you can add a simple 'Logging out…' message. It will only be displayed long enough for the page load workflow (see next step) to execute.
  2. From the Pages list, click the Logout settings cog to reveal the Logout page settings panel and click on Trigger Page Workflows. Create an On page load workflow and add the Xano Auth 'Logout' action.
  3. The 'Logout' action clears the session in the WeWeb front-end so the last action for this workflow can Navigate to an ungated page.
  1. In WeWeb, create a forgot password page. Use the Xano Auth provided 'Reset Password' UI block or create your own form.
  2. In the On submit Workflow for the form container, and a Xano Request action to auth/request-magic-link and pass the email form field as email.
  3. The Xano UI block contains variables and a message element that you can toggle for success/failure and configure the On error workflow as needed.
  4. When the user clicks on the link in the email triggered by the Xano endpoint, it will send them to the Verify screen.

Forgot Password

  1. In WeWeb, create a forgot password page. Use the Xano Auth provided 'Reset Password' UI block or create your own form.
  2. In the On submit Workflow for the form container, and a Xano Request action to auth/reset-password and pass the email form field as email.
  3. The Xano UI block contains variables and a message element that you can toggle for success/failure and configure the On error workflow as needed.
  4. When the user clicks on the link in the email triggered by the Xano endpoint, it will send them to the Reset Password screen.

Reset Password

  1. In WeWeb, create a reset password page. Use the Xano Auth provided 'Change Password' UI block or create your own form.
  2. From the Pages list, click the Reset Password settings cog to reveal the Reset Password page settings panel and click on Trigger Page Workflows. Create an On page load workflow.
  3. The workflow:
    1. Uses a True/False split to test if the Xano Auth isAuthenticated variable is set.
    2. If it is, Navigate to somewhere else like an auth-gated page.
    3. If it's not, uses a True/False split to test if the token variable is set.
    4. Calls a Xano Request action named Validated token to auth/magic-login passing the token variable as magic_token.
    5. Change variable value authToken to Validate token.result.data.authToken.
    6. Navigates home if the token variable isn't set.
    7. Will display an error if the On Error workflow handler is invoked.
3a835a76fc2c41caddf8f0a4aa81b03a_MD5.png
3a835a76fc2c41caddf8f0a4aa81b03a_MD5.png
  1. In the On submit Workflow for the form container, and a Xano Request action to auth/update-password and pass the password form fields as password and confirm_password and add to Headers an Authorization header with the value "Bearer " + authToken using the authToken variable which was set in the On page load workflow.
  2. The Xano UI block contains variables and a message element that you can toggle for success/failure and configure the On error workflow as needed.
📣
If you're new to WeWeb or Xano and found this guide helpful, sign up using my WeWeb referral link and/or my Xano referral link and you'll get a 10% discount as well as my appreciation.

What next?

This should cover the core auth-related workflows with a WeWeb and Xano stack.

From here you should be able to set auth-gating for your interior pages using On page load triggers with a Pass through condition that checks for the Xano Auth isAuthenticated variable for basic gating, or with checks against your roles property for roles-based permissions.

Published January 20, 2025