Rix is the official package layer for Vix.cpp Browse packages
Skip to content

Auth Quick Start

This page shows the shortest practical example for rix/auth.

The example uses the public Rix facade:

cpp
#include <rix.hpp>

and the Auth API through:

cpp
rix.auth

You will:

  1. create a memory auth service
  2. register a user
  3. login
  4. authenticate the session
  5. handle errors explicitly

Run as a single file

For the fastest test, create a small working folder:

bash
mkdir -p ~/rix-auth-quick-start
cd ~/rix-auth-quick-start

Create the file:

bash
touch auth.cpp

Add this code:

cpp
#include <rix.hpp>

int main()
{
  rix.debug.print("== rix/auth quick start ==");

  auto auth = rix.auth.memory();
  auto registered = auth.register_user({"ada@example.com","correct-password"});

  if (registered.failed())
  {
    const auto &error = registered.error();
    rix.debug.eprint(
        "auth error:",
        rix.auth.error.to_string(error),
        error.message()
    );

    return 1;
  }

  rix.debug.print("registered user");
  rix.debug.print("id:", registered.value().id());
  rix.debug.print("email:", registered.value().email());

  auto login = auth.login({"ada@example.com", "correct-password"});

  if (login.failed())
  {
    const auto &error = login.error();
    rix.debug.eprint(
        "auth error:",
        rix.auth.error.to_string(error),
        error.message()
    );

    return 1;
  }

  rix.debug.print("----------------------------------------");
  rix.debug.print("login successful");
  rix.debug.print("user:", login.value().user.email());
  rix.debug.print("session:", login.value().session.id());
  rix.debug.print("token issuer:", login.value().token.issuer());

  auto session = auth.authenticate_session(login.value().session.id());

  if (session.failed())
  {
    const auto &error = session.error();
    rix.debug.eprint(
        "auth error:",
        rix.auth.error.to_string(error),
        error.message()
    );

    return 1;
  }

  rix.debug.print("----------------------------------------");
  rix.debug.print("OK:", "session authenticated");
  rix.debug.print("session user id:", session.value().user_id());

  return 0;
}

Run it:

bash
vix run auth.cpp

If Rix is not available yet for single-file usage, install the facade globally:

bash
vix install -g rix/rix

Then run again:

bash
vix run auth.cpp

Expected output

The output should look like this:

txt
== rix/auth quick start ==
registered user
id: user_...
email: ada@example.com
----------------------------------------
login successful
user: ada@example.com
session: session_...
token issuer: rix/auth
----------------------------------------
OK: session authenticated
session user id: user_...

The exact user id and session id will be different.

Rix Auth generates secure ids for users, sessions, and tokens.

Use inside a Vix project

Create an application:

bash
vix new hello-auth --app
cd hello-auth

Add Rix:

bash
vix add rix/rix
vix install

Open:

txt
vix.app

Add the facade dependency:

txt
deps = [
  "rix/rix",
]

A small application manifest can look like this:

txt
name = "hello-auth"
type = "executable"
standard = "c++20"
output_dir = "bin"

sources = [
  "src/main.cpp",
]

include_dirs = [
  "include",
  "src",
]

deps = [
  "rix/rix",
]

packages = [
  "vix",
]

links = [
  "vix::vix",
]

resources = [
  ".env=.env",
]

Put the example code in:

txt
src/main.cpp

Build and run:

bash
vix build
vix run

Create the auth service

The quick start uses memory auth:

cpp
auto auth = rix.auth.memory();

This creates an authentication service with memory-backed user and session stores.

Use memory auth for:

  • examples
  • tests
  • local experiments
  • temporary tools

Memory auth does not persist data.

When the process exits, users and sessions are lost.

Register a user

Registration uses an email and a plain-text password:

cpp
auto registered = auth.register_user({"ada@example.com","correct-password"});

A successful registration returns a user:

cpp
registered.value().id()
registered.value().email()
registered.value().email_verified()
registered.value().active()

Always check the result before using .value():

cpp
if (registered.failed())
{
  const auto &error = registered.error();
  return 1;
}

Login

Login uses the same email and password:

cpp
auto login = auth.login({"ada@example.com","correct-password"});

A successful login returns three values:

cpp
login.value().user
login.value().session
login.value().token

The user is the authenticated identity.

The session is server-side login state.

The token is a short-lived value attached to the user.

Authenticate the session

After login, authenticate the session id:

cpp
auto session = auth.authenticate_session(login.value().session.id());

A session is usable when it is:

txt
valid
not revoked
not expired

If the result succeeds, the session contains the authenticated user id:

cpp
session.value().user_id()

Error handling

Rix Auth uses explicit results.

It does not use exceptions for normal authentication failures.

For operations that return data:

cpp
auto result = auth.login({"ada@example.com", "wrong-password"});

if (result.failed())
{
  const auto &error = result.error();
}

For operations that only return success or failure:

cpp
auto status = auth.logout(session_id);

if (status.failed())
{
  const auto &error = status.error();
}

Use the facade error helper to print a stable error name:

cpp
rix.auth.error.to_string(error)

Use the error message for diagnostics:

cpp
error.message()

Example:

cpp
if (login.failed())
{
  const auto &error = login.error();
  rix.debug.eprint(
      "auth error:",
      rix.auth.error.to_string(error),
      error.message()
  );

  return 1;
}

Try a failed login

Change the login password:

cpp
auto login = auth.login({"ada@example.com", "wrong-password"});

Run again:

bash
vix run auth.cpp

The login should fail.

This is expected.

Invalid credentials are normal authentication failures and are returned as explicit errors.

Add logout

After authenticating the session, revoke it:

cpp
auto logout = auth.logout(login.value().session.id());

if (logout.failed())
{
  const auto &error = logout.error();
  rix.debug.eprint(
      "auth error:",
      rix.auth.error.to_string(error),
      error.message()
  );

  return 1;
}

After logout, the same session should no longer authenticate:

cpp
auto after_logout = auth.authenticate_session(login.value().session.id());

if (after_logout.ok())
{
  return 1;
}

Logout revokes the session instead of deleting the authenticated user.

Use database auth later

For real applications, use database auth:

cpp
auto auth = rix.auth.database(db);

With production configuration:

cpp
auto config = rix.auth.config.production();

auto auth = rix.auth.database(db, config);

Memory auth is good for learning.

Database auth is the right direction when users and sessions must survive restarts.

What you should remember

Use the facade:

cpp
#include <rix.hpp>

Create memory auth:

cpp
auto auth = rix.auth.memory();

Register:

cpp
auto registered = auth.register_user({"ada@example.com", "correct-password"});

Login:

cpp
auto login = auth.login({"ada@example.com", "correct-password"});

Authenticate the session:

cpp
auto session = auth.authenticate_session(login.value().session.id());

Always check results before using .value().

Next step

Learn registration and login in more detail.

Next: Register and Login

Released under the MIT License.