Skip to main content

Authentication

The Member Portal uses Medplum's OAuth2 / PKCE-based authentication. There is no custom auth server — all login, session, and token management is handled by the Medplum SDK (useMedplum()).

Sign In page (/)

File: memberportal/src/pages/SignInPage.tsx

Patients can sign in using three methods:

1. Email + Password

  1. Patient enters email and password.
  2. The app calls medplum.startLogin({ email, password, projectId, scope }).
  3. Medplum handles PKCE internally and returns a LoginAuthenticationResponse.
  4. If MFA is required, the response includes mfaRequired: true — the UI switches to the MFA step.
  5. If no MFA, the response includes a code — the app calls medplum.processCode(code) to complete the login.

2. Google Sign-In

  1. Google's GSI script is loaded and renders a Google button.
  2. When the patient clicks it, Google returns a GoogleCredentialResponse.
  3. The app calls medplum.startGoogleLogin({ googleClientId, googleCredential, projectId, scope }).
  4. Same flow as above from step 3.

3. Microsoft SSO (Azure AD)

  1. Patient clicks the Microsoft button.
  2. The app redirects to Medplum's /auth/external endpoint.
  3. Medplum redirects to Microsoft, the patient authenticates, and Microsoft redirects back to / with a ?code= query param.
  4. On page load, SignInPage detects the code param and calls medplum.processCode(code).

Two-Factor Authentication (MFA)

If MFA is enabled on the account:

  • After password login, the UI switches from the credentials step to the mfa step.
  • Patient enters a 6-digit code from their authenticator app.
  • The app posts to auth/mfa/verify with { login, token }.
  • On success, the response contains a code — same processCode flow completes the login.

After sign in — where to redirect

Once logged in, the app checks whether the patient already has data:

Has active EHR connections?  OR  Has any FHIR data?
→ Redirect to Dashboard (/)
→ Otherwise redirect to Settings (/settings)

This ensures new patients who have not connected their EHR yet are sent to Settings to set up their account.

Sign Up (/register)

File: memberportal/src/pages/SignUpPage.tsx

New patients register with email and password. After registration, a verification email is sent.

Verify Email (/verifyemail/:id/:secret)

File: memberportal/src/pages/VerifyEmailPage.tsx

The link in the verification email opens this page. It completes email verification using the id and secret from the URL.

Set Password (/setpassword/:id/:secret)

File: memberportal/src/pages/SetPasswordPage.tsx

Used when a password reset link is clicked. The patient sets a new password using the id and secret from the URL.

Sign Out (/signout)

File: memberportal/src/pages/SignOutPage.tsx

Calls medplum.signOut() and redirects to /.

Session management

  • The Medplum SDK stores the access token and refresh token automatically.
  • medplum.isLoading() returns true while the SDK checks for an existing session on page load.
  • medplum.getProfile() returns the logged-in Patient resource, or undefined if not logged in.
  • There is no manual token management needed — the SDK handles refresh automatically.

Idle auto-logout

Authenticated sessions automatically expire after a period of inactivity. See Architecture — Idle Timeout for details.