Member Authentication

Add registration, login, page protection, and password reset to your published site.

Last updated: April 4, 2026

Overview

Site members are the end-users of your published website — completely separate from CMS admin users. Each workspace maintains its own member base (multi-tenant), and authentication uses secure httpOnly cookies so tokens are never accessible via JavaScript.

Enabling Member Auth

Go to Settings → Member Authentication in the admin panel and toggle Enable Member Auth. Once enabled, configure the following options:

SettingDescription
allowRegistrationAllow new members to self-register
requireEmailVerificationBlock login until email is verified
loginUrlPath to your login page (default: /login)
registerUrlPath to your registration page
afterLoginUrlRedirect destination after successful login
afterLogoutUrlRedirect destination after logout

Building Auth Pages

Create dedicated pages and blocks for the auth flow. Recommended pages: /login, /register, /forgot-password, /reset-password, and /verify-email.

Login Block

const result = await context.auth.login(email, password);
if (result.success) {
  window.location.href = redirectUrl;
} else {
  showError(result.message);
}

Register Block

const result = await context.auth.register(email, password, {
  firstName: "Jane",
  lastName: "Doe"
});
// Show "check your email" on success

Logout

await context.auth.logout();
window.location.href = "/";

Forgot Password Block

await context.graphql(`
  mutation($wid: ID!, $email: String!) {
    siteMemberRequestPasswordReset(
      workspaceId: $wid, email: $email
    ) { success message }
  }
`, { wid: context.workspace.id, email });

Reset Password Block

Read ?token= from URL:

const token = new URLSearchParams(location.search).get("token");
await context.graphql(`
  mutation($token: String!, $pw: String!) {
    siteMemberResetPassword(token: $token, newPassword: $pw) {
      success message
    }
  }
`, { token, pw: newPassword });

Verify Email Block

const token = new URLSearchParams(location.search).get("token");
await context.graphql(`
  mutation($token: String!) {
    siteMemberVerifyEmail(token: $token) { success message }
  }
`, { token });

Auth Context in Blocks

context.auth is available in any block when member auth is enabled. Functions are client-side only.

Property / MethodTypeDescription
context.auth.isAuthenticatedbooleanWhether current visitor is logged in
context.auth.memberobject{ id, email, role, isVerified, profile }
context.auth.login(email, pw)PromiseReturns { success, message }
context.auth.register(email, pw, profile?)PromiseReturns { success, message }
context.auth.logout()PromiseClears session cookie

Conditional Rendering

if (context.auth.isAuthenticated) {
  const { displayName } = context.auth.member.profile;
  // show member content
} else {
  // show login prompt
}

Page Protection

Protect pages server-side via access control settings. Unauthenticated users redirect to loginUrl before any HTML is sent.

SettingDescription
requireAuth: trueRedirect unauthenticated visitors
allowedRoles: ["premium"]Restrict to specific roles

Member Roles

Default roles: Guest, Member (default on registration), Premium. Custom roles configurable per workspace.

Member Profile

  • firstName, lastName, displayName
  • avatarUrl, phone
  • customFields — workspace-defined extra fields

Password Requirements

  • Min 8 characters, one uppercase, one lowercase, one number

Email Verification Flow

  1. Register → status pending, verification email sent
  2. Click link → /verify-email?token=xxx → status active
  3. If requireEmailVerification: true, login blocked until verified

Password Reset Flow

  1. Forgot password form → reset email sent
  2. Click link → /reset-password?token=xxx → new password
  3. Token expires after 1 hour

Session

JWT in httpOnly cookie, 7-day expiry. Auto-forwarded on all block GraphQL requests. No manual token management needed.

Tips

  • Create all 5 auth pages: /login, /register, /forgot-password, /reset-password, /verify-email
  • Protected pages redirect to /login by default (configurable per page)
  • context.auth functions are client-side only
  • Use context.auth.isAuthenticated to show/hide content conditionally
  • All member data is workspace-scoped (multi-tenant safe)
Member Authentication | Cmssy