Users live in the _User class. Parse handles passwords (hashed, never returned), sessions and permissions; you choose in the dashboard how users may log in and what the rules are. Everything below is in App Settings › Users and App Settings › Emails & Hosting.
Sign up and log in
const user = new Parse.User();
user.set('username', 'ada@example.com');
user.set('email', 'ada@example.com');
user.set('password', 'a-long-password');
await user.signUp();
await Parse.User.logIn('ada@example.com', 'a-long-password');
const current = Parse.User.current(); // the logged-in user, kept between visits
await Parse.User.logOut();
After login, every request carries the user's session, so class-level permissions and ACLs apply to them. Username and password login is on by default (User Authentication › Allow username and password-based authentication).
Email verification
Turn on Emails & Hosting › Verify user emails: a verification email goes out on sign-up, and the user's emailVerified field shows whether they clicked it. In the same section set the sender address, display name and reply-to address, and edit the email templates. The sender address must be on a domain you own.
Password reset
await Parse.User.requestPasswordReset('ada@example.com');
The user gets an email with a link to a page where they choose a new password. Password Policy › Reset link validity (hours) sets how long the link works. You can replace the hosted pages with your own (Emails & Hosting: custom "choose a new password", "password changed", "email verified" and invalid-link pages).
Sessions
| Setting (User Sessions) | |
|---|---|
| Session length (days) | How long a login lasts |
| Expire inactive sessions | End sessions that aren't used |
| Revoke session on password change | Log out other devices when the password changes |
Password policy and lockout
| Setting | |
|---|---|
| Password pattern | A regular expression new passwords must match |
| Password expires after (days) | Force a change after this many days |
| Password history | Refuse the last N passwords |
| Lock accounts after failed logins | With Failed attempts and Lock for (minutes): slows down password guessing |
Anonymous users
User Authentication › Allow anonymous users lets an app create a user without credentials (Parse.AnonymousUtils.logIn()), e.g. to save a cart before sign-up, and link a real login to it later. Leave it off if your app doesn't use it.
Multi-factor authentication
Users can protect their account with an authenticator app (Google Authenticator, 1Password, Authy...): after their password, they enter the app's 6-digit code. Turn it on in App Settings › Users › Allow multi-factor authentication. It's available on Parse Server 8.6.104 and newer; earlier versions have flaws in it, so the option isn't offered there.
Your app adds two things: a screen to set it up, and the code field at login. With the JS SDK and the otpauth library:
import * as OTPAuth from 'otpauth';
// set up, while the user is logged in
const secret = new OTPAuth.Secret({ size: 20 });
const totp = new OTPAuth.TOTP({ issuer: 'My App', label: user.get('username'), secret });
showQrCode(totp.toString()); // otpauth://totp/... for the authenticator app
const code = await askForCode(); // the code the app now shows
await user.linkWith('mfa', { authData: { secret: secret.base32, token: code } });
const recovery = user.get('authDataResponse').mfa.recovery; // 2 one-time recovery codes
showRecoveryCodes(recovery);
// log in: the password alone is refused once MFA is on
await Parse.User.logInWithAdditionalAuth(username, password, { mfa: { token: code } });
- A wrong code is refused with
Invalid MFA token, a login without one withMissing additional authData mfa. Ask for the code when you get the latter. - Each recovery code works once, in place of the app's code, e.g. after losing the phone. Ask users to keep them somewhere safe.
- The user's
authData.mfashows only{ "status": "enabled" }: the secret never leaves the server. - Over REST, send the same
authDatawithPUT /users/<id>(to set it up) andPOST /login(to log in).
Social login
Turn each provider on in App Settings › Users › Social Login and enter its credentials:
| Provider | What SashiDo needs |
|---|---|
| Apple | Bundle ID |
| Your apps' OAuth client IDs (iOS, Android, web) | |
| App ID and App Secret | |
| GitHub, LinkedIn | Client ID and secret of your OAuth app |
| Microsoft | Client ID and secret (Parse Server 4.1 and newer) |
| Consumer Key and Consumer Secret |
Your app gets the provider's token with the provider's SDK, then logs in to Parse with it, which creates the user on the first login:
// e.g. after Sign in with Apple returned an identity token
await Parse.User.logInWith('apple', {
authData: { id: appleUserId, token: identityToken },
});
Each provider's authData fields are in Parse's third-party authentication guide.
From Parse Server 8, Google requires your client IDs, and GitHub, LinkedIn and Microsoft verify an authorization code with your client secret instead of trusting a token from the app. Fill these in before you upgrade: the version change is refused while they're missing.
Protect the users
_Useris readable by everyone by default: anyone with your client keys can list your users. In Core › Browser › _User › Security, allow Find only to roles or the master key; sign-up, login and fetching the current user keep working.- Never store secrets in public
_Userfields; use a class only the user's ACL can read. - Secure your app covers permissions in depth, and
get_app_advicethrough MCP checks them for you.