Docs

Authentication

Appwrite provides authentication for many different use cases to fit the needs of developers. Appwrite manages authentication with a combination of accounts and sessions. Accounts can be created in many different ways, such as through an anonymous session, email and password, OAuth authentication, magic URLs, and more.

Account vs Users API

The Account API operates in the scope of the currently logged-in account and is usually used in a frontend or mobile app. The Users API is used in backend integrations and uses an API key with access to all your project users.

Some of the Account API methods are available from Server SDKs when you authenticate with a JWT. This allows your Server SDK to perform actions on behalf of a user.

Create An Account

A user account in Appwrite is the primary way to access information for a given project. Accounts can be created in many different ways, including email & password, anonymous sessions, OAuth2, phone authentication, and more. Applications can create and manage sessions through the REST API or Client SDKs.

Email

Creating an account via email and password is one of the most common ways to sign up for an application. Appwrite provides email and password authentication out of the box. Using one of Appwrite's Client SDKs, or the REST APIs directly, you can create an account using an email address and password in your application.

Passwords are hashed with Argon2, a resilient and secure password hashing algorithm.

The example below shows you how to create an account:

  • Web

    import { Client, Account, ID } from "appwrite";
    
    const client = new Client()
        .setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
        .setProject('5df5acd0d48c2');               // Your project ID
    
    const account = new Account(client);
    
    const promise = account.create(
        ID.unique(),
        'team@appwrite.io',
        'password'
    );
    
    promise.then(function (response) {
        console.log(response);
    }, function (error) {
        console.log(error);
    });
  • Flutter

    import 'package:appwrite/appwrite.dart';
    
    final client = Client()
        .setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
        .setProject('5df5acd0d48c2');               // Your project ID
    
    final account = Account(client);
    
    final user = await account.create(
        userId: ID.unique(),
        email: 'team@appwrite.io',
        password: 'password',
    );
  • Apple

    import Appwrite
    
    let client = Client()
        .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint
        .setProject("5df5acd0d48c2")                // Your project ID
    
    let account = Account(client)
    
    let user = try await account.create(
        userId: ID.unique(),
        email: "team@appwrite.io",
        password: "password"
    )
  • Android

    import io.appwrite.Client
    import io.appwrite.services.Account
    import io.appwrite.ID
    
    val client = Client()
        .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint
        .setProject("5df5acd0d48c2")                // Your project ID
    
    val account = Account(client)
    
    val user = account.create(
        userId = ID.unique(),
        email = "team@appwrite.io",
        password = "password"
    )

After an account is created, it can be verified through the account verification route provided by the Appwrite Accounts API. The user doesn't need to be verified to log in, but you can restrict resource access to verified users only using permissions.

Anonymous User

Anonymous authentication allows users of your application to create a temporary valid session without creating an account. The session has an expiration time of one year. If an account is created while an anonymous session is active, it will be attached to the existing anonymous session.

  • Web

    import { Client, Account } from "appwrite";
    
    const client = new Client()
        .setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
        .setProject('5df5acd0d48c2');               // Your project ID
    
    const account = new Account(client);
    
    const promise = account.createAnonymousSession();
    
    promise.then(function (response) {
        console.log(response);
    }, function (error) {
        console.log(error);
    });
  • Flutter

    import 'package:appwrite/appwrite.dart';
    
    final client = Client()
        .setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
        .setProject('5df5acd0d48c2');               // Your project ID
    
    final account = Account(client);
    
    final user = await account.createAnonymousSession();
  • Apple

    import Appwrite
    
    let client = Client()
        .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint
        .setProject("5df5acd0d48c2")                // Your project ID
    
    let account = Account(client)
    
    let user = try await account.createAnonymousSession()
  • Android

    import io.appwrite.Client
    import io.appwrite.services.Account
    
    val client = Client()
        .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint
        .setProject("5df5acd0d48c2")                // Your project ID
    
    val account = Account(client)
    
    val user = account.createAnonymousSession()

OAuth

OAuth is another way to authenticate a user using a multistep process. When using OAuth to authenticate, the authentication request is initiated from the client application. The user is then redirected to an OAuth2 provider to complete the authentication step, and finally, the user is redirected back to the client application. This provides integration with many third-party services that provide their own OAuth integration as a more secure approach than providing a username/password directly.

In applications with first-party redirects, using OAuth2 for authentication is preferred.

The example below shows you how to authenticate with OAuth2 using Amazon's OAuth system.

  • Web

    import { Client, Account } from "appwrite";
    
    const client = new Client();
        .setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
        .setProject('5df5acd0d48c2');               // Your project ID
    
    const account = new Account(client);
    
    // Go to OAuth provider login page
    account.createOAuth2Session('amazon');
  • Flutter

    import 'package:appwrite/appwrite.dart';
    
    final client = Client()
        .setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
        .setProject('5df5acd0d48c2');               // Your project ID
    
    final account = Account(client);
    
    // Go to OAuth provider login page
    await account.createOAuth2Session(provider: 'amazon');
  • Apple

    import Appwrite
    
    let client = Client()
        .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint
        .setProject("5df5acd0d48c2")                // Your project ID
    
    let account = Account(client)
    
    // Go to OAuth provider login page
    try await account.createOAuth2Session(provider: "amazon")
  • Android

    import io.appwrite.Client
    import io.appwrite.services.Account
    
    val client = Client()
        .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint
        .setProject("5df5acd0d48c2")                // Your project ID
    
    val account = Account(client)
    
    // Go to OAuth provider login page
    account.createOAuth2Session(provider = "amazon")

If there is already an active anonymous session, the new session will be attached to it. If there are no active sessions, the server will attempt to look for an account with the same email address as the email received from the OAuth2 provider and attach the new session to the existing account. If no matching account is found - the server will create a new account.

Phone

Phone authentication is done using a two-step authentication process. When using phone authentication, the authentication request is initiated from the client application and an SMS is sent to the user with a secret key for creating a session.

Phone authentication requires you to set up an SMS provider to send SMS messages. You will need to configure these environment variables and restart your Appwrite containers before you can use phone authentication.

The example below shows you how to initiate a phone authentication request.

  • Web

    import { Client, Account, ID } from "appwrite";
    
    const client = new Client()
        .setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
        .setProject('5df5acd0d48c2');               // Your project ID
    
    const account = new Account(client);
    
    const promise = account.createPhoneSession(
        ID.unique(),
        '+16171234567'
    );
    
    promise.then(function (response) {
        console.log(response);
    }, function (error) {
        console.log(error);
    });
    
    
  • Flutter

    import 'package:appwrite/appwrite.dart';
    
    final client = Client()
        .setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
        .setProject('5df5acd0d48c2');               // Your project ID
    
    final account = Account(client);
    
    final session = await account.createPhoneSession(
        userId: ID.unique(),
        phone: '+16171234567'
    );
  • Apple

    import Appwrite
    
    let client = Client()
        .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint
        .setProject("5df5acd0d48c2")                // Your project ID
    
    let account = Account(client)
    
    let session = try await account.createPhoneSession(
        userId: ID.unique(),
        phone: "+16171234567"
    )
  • Android

    import io.appwrite.Client
    import io.appwrite.services.Account
    import io.appwrite.ID
    
    val client = Client()
        .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint
        .setProject("5df5acd0d48c2")                // Your project ID
    
    val account = Account(client)
    
    val session = account.createPhoneSession(
        userId = ID.unique(),
        phone = "+16171234567"
    )

After initiation, the returned user ID and secret are used to confirm the user. The secret will be a 6-digit number in the SMS message sent to the user.

  • Web

    import { Client, Account, ID } from "appwrite";
    
    const client = new Client()
        .setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
        .setProject('5df5acd0d48c2');               // Your project ID
    
    const account = new Account(client);
    
    const promise = account.updatePhoneSession(
        ID.unique(),
        '[SECRET]'
    );
    
    promise.then(function (response) {
        console.log(response);
    }, function (error) {
        console.log(error);
    });
  • Flutter

    import 'package:appwrite/appwrite.dart';
    
    final client = Client()
        .setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
        .setProject('5df5acd0d48c2');               // Your project ID
    
    final account = Account(client);
    
    final session = await account.updatePhoneSession(
        userId: ID.unique(),
        secret: '[SECRET]'
    );
  • Apple

    import Appwrite
    
    let client = Client()
        .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint
        .setProject("5df5acd0d48c2")                // Your project ID
    
    let account = Account(client)
    
    let session = try await account.updatePhoneSession(
        userId: ID.unique(),
        secret: "[SECRET]"
    )
  • Android

    import io.appwrite.Client
    import io.appwrite.services.Account
    import io.appwrite.ID
    
    val client = Client()
        .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint
        .setProject("5df5acd0d48c2")                // Your project ID
    
    val account = Account(client)
    
    val session = account.updatePhoneSession(
        userId = ID.unique(),
        secret = "[SECRET]"
    )

After the secret is verified, a session will be created.

Login

Logging in with an email and password is one of the most common ways to login into an application.

The example below shows you how to create a session:

  • Web

    import { Client, Account } from "appwrite";
    
    const client = new Client()
        .setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
        .setProject('5df5acd0d48c2');               // Your project ID
    
    const account = new Account(client);
    
    const promise = account.createEmailSession(
        'team@appwrite.io',
        'password'
    );
    
    promise.then(function (response) {
        console.log(response);
    }, function (error) {
        console.log(error);
    });
  • Flutter

    import 'package:appwrite/appwrite.dart';
    
    final client = Client()
        .setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
        .setProject('5df5acd0d48c2');               // Your project ID
    
    final account = Account(client);
    
    final session = await account.createEmailSession(
        email: 'team@appwrite.io',
        password: 'password'
    );
  • Apple

    import Appwrite
    
    let client = Client()
        .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint
        .setProject("5df5acd0d48c2")                // Your project ID
    
    let account = Account(client)
    
    let session = try await account.createEmailSession(
        email: "team@appwrite.io",
        password: "password"
    )
  • Android

    import io.appwrite.Client
    import io.appwrite.services.Account
    
    val client = Client()
        .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint
        .setProject("5df5acd0d48c2")                // Your project ID
    
    val account = Account(client)
    
    val session = account.createEmailSession(
        email = "team@appwrite.io",
        password = "password"
    )

When a user tries to access restricted resources, you can check if they have a valid, active session. The Account Service provides a get() method that checks whether the current user session is active and returns the account information if successful.

The example below shows you how to check whether there is an active session:

  • Web

    import { Client, Account } from "appwrite";
    
    const client = new Client()
        .setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
        .setProject('5df5acd0d48c2');               // Your project ID
    
    const account = new Account(client);
    
    const promise = account.get();
    
    promise.then(function (response) {
        console.log(response);
    }, function (error) {
        console.log(error);
    });
  • Flutter

    import 'package:appwrite/appwrite.dart';
    
    final client = Client()
        .setEndpoint('https://[HOSTNAME_OR_IP]/v1') // Your API Endpoint
        .setProject('5df5acd0d48c2');               // Your project ID
    
    final account = Account(client);
    
    final session = await account.get();
  • Apple

    import Appwrite
    
    let client = Client()
        .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint
        .setProject("5df5acd0d48c2")                // Your project ID
    
    let account = Account(client)
    
    let session = try await account.get()
  • Android

    import io.appwrite.Client
    import io.appwrite.services.Account
    
    val client = Client()
        .setEndpoint("https://[HOSTNAME_OR_IP]/v1") // Your API Endpoint
        .setProject("5df5acd0d48c2")                // Your project ID
    
    val account = Account(client)
    
    val session = account.get()

An authenticated session in Appwrite lasts for 1 year and is then automatically expired.

Persistence

Appwrite handles the persistence of the session in a consistent way across SDKs. After authenticating with an SDK, the SDK will persist the session so that the user will not need to log in again the next time they open the app. The mechanism for persistence depends on the SDK.

Best Practice

Only keep user sessions active as long as needed and only maintain one instance of the Client SDK in your app to avoid conflicting session data.

SDK Persistence Method
Web Uses a session secure cookie and falls back to local storage when a session cookie is not available.
Flutter Uses a session cookie stored in Application Documents through the path_provider package.
Apple Uses a session cookie stored in UserDefaults.
Android Uses a session cookie stored in SharedPreferences.

Security

Security is very important to protect users' data and privacy. Appwrite uses a permissions model coupled with user sessions to ensure users only have access to certain information based on the permissions. With Appwrite services, including databases and storage, access is granted at the collection, bucket, document, or file level. This access is consistent across access to these items in relation to document access, file access, and real-time events.