Authentication
Etebase automatically takes care of the encryption for you, securely deriving an encryption key from the user password. It then also creates an asymmetric keypair to login so the password never leaves the user's device.
important
Please note that all of the operations in this page are slow and may take a few seconds to complete depending on your device. This is because Etebase purposefully uses a slow function (Argon2id) to derive a secure encryption key from the user password.
Luckily they can be avoided almost entirely for most use-cases. Please take a look at session save and restore for more information.
Signup
Sign up is just one easy call which returns an instance of the main etebase class.
When using a private server, make sure that either sign up is enabled, or that you have created a user beforehand using the Django Admin panel.
- JavaScript
- Python
- Java
- Kotlin
- C/C++
- Rust
// serverUrl can be obtained from the dashboard (or omitted for default)
const etebase = await Etebase.Account.signup({
username: "username",
email: "email"
}, "password", serverUrl);
from etebase import Client, Account, User
# server_url can be obtained from the dashboard (or omitted for default)
client = Client("client-name", server_url)
user = User("username", "test@example.com")
etebase = Account.signup(client, user, "password")
import com.etebase.client.*;
import okhttp3.OkHttpClient;
OkHttpClient httpClient = new OkHttpClient.Builder().build();
User user = new User("username", "text@example.com");
// serverUrl can obtained from the dashboard (or null for default)
Client client = Client.create(httpClient, serverUrl);
Account etebase = Account.signup(client, user, "password");
import com.etebase.client.*
import okhttp3.OkHttpClient;
val httpClient: OkHttpClient = Builder().build()
val user = User("username", "text@example.com")
// serverUrl can obtained from the dashboard (or null for default)
val client = Client.create(httpClient, serverUrl)
val etebase = Account.signup(client, user, "password")
// Your personal server url can be obtained from the dashboard
const char *server_url = etebase_get_default_server_url();
EtebaseClient *client = etebase_client_new("client-name", server_url);
EtebaseUser *user = etebase_user_new("username", "test@example.com");
EtebaseAccount *etebase = etebase_account_signup(client, user, "password");
use etebase::{Account, Client, User};
let user = User::new("username", "text@example.com");
let client = Client::new(..., server_url)?;
let etebase = Account::signup(client, user, "password")?;
Login
Login is also just one easy call which returns an instance of the main etebase class.
- JavaScript
- Python
- Java
- Kotlin
- C/C++
- Rust
// serverUrl can be obtained from the dashboard (or omitted for default)
const etebase = await Etebase.Account.login("username", "password", serverUrl);
from etebase import Client, Account
# server_url can be obtained from the dashboard (or omitted for default)
client = Client("client-name", server_url)
etebase = Account.login(client, "username", "password")
import com.etebase.client.*;
import okhttp3.OkHttpClient;
OkHttpClient httpClient = new OkHttpClient.Builder().build();
// serverUrl can obtained from the dashboard (or null for default)
Client client = Client.create(httpClient, serverUrl);
Account etebase = Account.login(client, "username", "password");
import com.etebase.client.*
import okhttp3.OkHttpClient;
val httpClient: OkHttpClient = Builder().build()
// serverUrl can obtained from the dashboard (or null for default)
val client = Client.create(httpClient, serverUrl)
val etebase = Account.login(client, "username", "password")
// Your personal server url can be obtained from the dashboard
const char *server_url = etebase_get_default_server_url();
EtebaseClient *client = etebase_client_new("client-name", server_url);
EtebaseAccount *etebase = etebase_account_login(client, "username", "password");
use etebase::{Account, Client};
let client = Client::new(..., server_url)?;
let etebase = Account::login(client, "username", "password")?;
Change password
Unlike signup and login, changing password requires an already set up etebase object.
- JavaScript
- Python
- Java
- Kotlin
- C/C++
- Rust
await etebase.changePassword("new password");
etebase.change_password("new password")
etebase.changePassword("new password");
etebase.changePassword("new password")
etebase_account_change_password(account, "new password");
etebase.change_password("new password")?;
Logout
- JavaScript
- Python
- Java
- Kotlin
- C/C++
- Rust
await etebase.logout();
etebase.logout()
etebase.logout();
etebase.logout()
etebase_account_logout(account);
etebase.logout()?;
Session save and restore
Most apps can't, or don't want the user to enter their passwords every time they are opened, that's why Etebase supports saving and restoring sessions.
Saving and restoring a session is as simple as:
- JavaScript
- Python
- Java
- Kotlin
- C/C++
- Rust
const etebase = await Etebase.Account.login("username", "password", serverUrl);
const savedSession = await etebase.save();
// Later on...
const etebase = await Etebase.Account.restore(savedSession);
from etebase import Client, Account
client = Client("client-name", server_url)
etebase = Account.login(client, "username", "password")
stored_session = etebase.save(None)
# later on...
etebase = Account.restore(client, stored_session, None)
import com.etebase.client.*;
Client client = Client.create(httpClient, serverUrl);
Account etebase = Account.login(client, "username", "password");
String storedSession = etebase.save(null);
// later on...
Account etebase = Account.restore(client, storedSession, null);
import com.etebase.client.*
val client = Client.create(httpClient, serverUrl)
val etebase = Account.login(client, "username", "password")
val storedSession = etebase.save(null)
// later on...
val etebase = Account.restore(client, storedSession, null)
const char *server_url = etebase_get_default_server_url();
EtebaseClient *client = etebase_client_new("client-name", server_url);
EtebaseAccount *etebase = etebase_account_login(client, "username", "password");
char *stored_session = etebase_account_save(etebase, NULL, 0);
// later on...
EtebaseAccount *etebase = etebase_account_restore(client, stored_session, NULL, 0);
free(stored_session);
use etebase::{Account, Client};
let client = Client::new(..., server_url)?;
let etebase = Account::login(client, "username", "password")?;
let stored_session = etebase.save(None)?;
// later on...
let etebase = Account::restore(client, stored_session, None)?;
Encrypting the stored session
While the above works, it's advised to encrypt the stored session with a randomly generated key that is stored securely (e.g. in the operating system's key store), or securely derived from a user storage password.
- JavaScript
- Python
- Java
- Kotlin
- C/C++
- Rust
const etebase = await Etebase.Account.login("username", "password");
// Save the key somewhere safe (e.g. the OS's key store)
const encryptionKey = Etebase.randomBytes(32);
const savedSession = await etebase.save(encryptionKey);
// Later on...
const etebase = await Etebase.Account.restore(savedSession, encryptionKey);
from etebase import Client, Account, random_bytes
client = Client("client-name")
etebase = Account.login(client, "username", "password")
# Save the key somewhere safe (e.g. the OS's key store)
encryption_key = random_bytes(32)
stored_session = etebase.save(encryption_key)
# later on...
etebase = Account.restore(client, stored_session, encryption_key)
import com.etebase.client.*;
Client client = Client.create(httpClient, null);
Account etebase = Account.login(client, "username", "password");
// Save the key somewhere safe (e.g. the OS's key store)
byte[] encryptionKey = Utils.randomBytes(32);
String storedSession = etebase.save(encryptionKey);
// later on...
Account etebase = Account.restore(client, storedSession, encryptionKey);
import com.etebase.client.*
val client = Client.create(httpClient, null)
val etebase = Account.login(client, "username", "password")
// Save the key somewhere safe (e.g. the OS's key store)
val encryptionKey = Utils.randomBytes(32)
val storedSession = etebase.save(encryptionKey)
// later on...
val etebase = Account.restore(client, storedSession, encryptionKey)
const char *server_url = etebase_get_default_server_url();
EtebaseClient *client = etebase_client_new("client-name", server_url);
EtebaseAccount *etebase = etebase_account_login(client, "username", "password");
// Save the key somewhere safe (e.g. the OS's key store)
char encryption_key[32];
etebase_utils_randombytes(encryption_key, sizeof(encryption_key));
char *stored_session = etebase_account_save(etebase,encryption_key, sizeof(encryption_key));
// later on...
EtebaseAccount *etebase = etebase_account_restore(client, stored_session, encryption_key, sizeof(encryption_key));
free(stored_session);
use etebase::{Account, Client, utils};
let client = Client::new(..., server_url)?;
let etebase = Account::login(client, "username", "password")?;
// Save the key somewhere safe (e.g. the OS's key store)
let encryption_key = utils::randombytes(32);
let stored_session = etebase.save(Some(encryption_key))?;
// later on...
let etebase = Account::restore(client, stored_session, Some(encryption_key))?;
Email as username
In some cases you don't want a separate username, and would instead like users to be able to login using just their email address. Etebase supports this out of the box, just pass the email instead of the username in the login
and anywhere else where Etebase accepts a username.
Etebase however still needs a unique username passed to it during signup, though it can just be randomly generated. So for example, you can use the Etebase utils to generate a username like shown in this psuedo-code:
username = toBase64(randomBytes(24));
Using custom servers
Checking custom server URLs
The login and signup operations above automatically check whether the URL passed is pointing to a valid Etebase server. However, some applications need to know if the URL is pointing to a valid server before asking for credentials. This function does exactly that.
- JavaScript
- Python
- Java
- Kotlin
- C/C++
- Rust
const isEtebase = await Etebase.Account.isEtebaseServer("https://example.com");
from etebase import Client, Account
client = Client("client-name", "https://example.com")
is_etebase = Account.is_etebase_server(client)
import com.etebase.client.*;
import okhttp3.OkHttpClient;
OkHttpClient httpClient = new OkHttpClient.Builder().build();
Client client = Client.create(httpClient, "https://example.com");
boolean isEtebase = Account.isEtebaseServer(client);
import com.etebase.client.*
import okhttp3.OkHttpClient;
val httpClient: OkHttpClient = Builder().build()
val client = Client.create(httpClient, "https://example.com")
val isEtebase = Account.isEtebaseServer(client)
EtebaseClient *client = etebase_client_new("client-name", "https://example.com");
// Returns 0 if client is pointing an etebase server, 1 if not, -1 on error
int32_t is_etebase = etebase_account_check_etebase_server(client);
use etebase::{Account, Client};
let client = Client::new(..., server_url)?;
let is_etebase = Account::is_etebase_server(client)?;
Forcing server URL for local development
When saving etebase instances with cacheSave
the server URL is also being saved. This is not an issue in production as the URL of the server is unlikely to change, however, when developing against a local server it's often useful to force the server URL without having to login again.
- JavaScript
- Python
- Java
- Kotlin
- C/C++
- Rust
const etebase = await Etebase.Account.restore(savedSession);
etebase.serverUrl = "http://new-development-server";
etebase = Account.restore(client, stored_session, None)
etebase.force_server_url("http://new-development-server")
Account etebase = Account.restore(client, storedSession, null);
etebase.forceServerUrl("http://new-development-server");
val etebase = Account.restore(client, storedSession, null)
etebase.forceServerUrl("http://new-development-server")
EtebaseAccount *etebase = etebase_account_restore(client, stored_session, NULL, 0);
etebase_account_force_server_url(etebase, "http://new-development-server");
let mut etebase = Account::restore(client, stored_session, None)?;
etebase.force_server_url("http://new-development-server")?;