Register and Login
This page explains how to register users and authenticate them with rix/auth.
The examples use the public Rix facade:
#include <rix.hpp>and the Auth API through:
rix.authRegistration creates a user.
Login verifies the user credentials and creates an authenticated session.
Basic flow
The normal flow is:
register_user
-> validate email and password
-> hash password
-> create user
login
-> find user by email
-> verify password
-> create session
-> issue token
authenticate_session
-> validate session id
-> reject expired or revoked sessionsComplete example
Create a file:
mkdir -p ~/rix-auth-register-login
cd ~/rix-auth-register-login
touch auth.cppAdd:
#include <rix.hpp>
int main()
{
rix.debug.print("== rix/auth register and login ==");
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:
vix run auth.cppIf Rix is not available yet for single-file usage:
vix install -g rix/rix
vix run auth.cppRegister a user
Use:
auto registered = auth.register_user({"ada@example.com", "correct-password"});The request contains:
email
passwordThe password is plain text at the API boundary.
Rix Auth validates it and stores only a password hash in the user store.
A successful result contains a User:
registered.value().id()
registered.value().email()
registered.value().email_verified()
registered.value().active()
registered.value().created_at()
registered.value().updated_at()Do not expose or log the password hash in application output.
Check registration errors
Always check the result before using .value():
if (registered.failed())
{
const auto &error = registered.error();
rix.debug.eprint(
"auth error:",
rix.auth.error.to_string(error),
error.message()
);
return 1;
}Common registration failures include:
InvalidEmail
InvalidPassword
UserAlreadyExists
StoreError
CryptoErrorLogin a user
Use:
auto login = auth.login({"ada@example.com", "correct-password"});A successful login contains:
login.value().user
login.value().session
login.value().tokenThe user is the authenticated identity.
The session is the server-side authentication state.
The token is a short-lived value attached to the authenticated user.
Check login errors
Always check the login result:
if (login.failed())
{
const auto &error = login.error();
rix.debug.eprint(
"auth error:",
rix.auth.error.to_string(error),
error.message()
);
return 1;
}Common login failures include:
InvalidEmail
InvalidPassword
UserNotFound
InvalidCredentials
EmailVerificationRequired
UserDisabled
StoreErrorFor public login responses, avoid revealing whether the email exists.
The application can return a generic message such as:
Invalid email or password.while logs can keep the internal error code for diagnostics.
Read the login result
After a successful login:
const auto &result = login.value();
rix.debug.print("user:", result.user.email());
rix.debug.print("session:", result.session.id());
rix.debug.print("token issuer:", result.token.issuer());The session id and token value are sensitive.
In production, avoid logging:
session ids
raw token values
password hashes
plain-text passwordsAuthenticate a session
After login, use the session id to authenticate later requests:
auto session = auth.authenticate_session(login.value().session.id());A successful result contains a usable Session:
session.value().id()
session.value().user_id()
session.value().created_at()
session.value().expires_at()
session.value().last_seen_at()
session.value().revoked()A session is usable when it is:
valid
not revoked
not expiredFailed login example
Change the password:
auto login = auth.login({"ada@example.com", "wrong-password"});Then run again:
vix run auth.cppThe login should fail.
This is expected.
Invalid credentials are normal authentication failures and are returned through the result object.
Duplicate registration example
If you register the same email twice:
auto first = auth.register_user({"ada@example.com", "correct-password"});
auto second = auth.register_user({"ada@example.com", "correct-password"});The second registration should fail.
You can check the error:
if (second.failed())
{
const auto &error = second.error();
if (rix.auth.error.is(
error,
rixlib::auth::AuthErrorCode::UserAlreadyExists
))
{
rix.debug.eprint("user already exists");
}
}Use a custom configuration
Registration and login use the active Auth configuration.
Example:
auto config = rix.auth.config.development();
config.set_min_password_length(10);
config.set_issuer("my-app");
auto auth = rix.auth.memory(config);Now passwords shorter than the configured minimum length are rejected.
For real applications, start from production configuration:
auto config = rix.auth.config.production();
auto auth = rix.auth.database(db, config);Email verification
Production configuration can require verified email addresses before login:
auto config = rix.auth.config.production();
config.set_require_email_verification(true);
auto auth = rix.auth.memory(config);If the user is not verified, login can fail with:
EmailVerificationRequiredThe user model exposes:
user.email_verified()
user.set_email_verified(true)In a real application, email verification is usually handled by a higher-level flow around Auth.
Inactive users
Auth can reject inactive users:
auto config = rix.auth.config.production();
config.set_reject_inactive_users(true);The user model exposes:
user.active()
user.set_active(false)If an inactive user tries to login, Auth can return:
UserDisabledMemory store behavior
The examples use:
auto auth = rix.auth.memory();This keeps users and sessions in memory.
That means:
data is lost when the process exits
it is useful for examples and tests
it is not durableUse memory auth for learning and test scenarios.
Use database auth when users and sessions must persist.
Database-backed login
For real applications:
auto config = rix.auth.config.production();
auto auth = rix.auth.database(db, config);Database auth uses database-backed user and session stores.
The tables are created by the database store layer when schema creation is enabled.
Use database auth when authentication data must survive restarts.
Error handling pattern
Use the same pattern for every Auth operation.
For result-returning operations:
auto result = auth.login({"ada@example.com", "correct-password"});
if (result.failed())
{
const auto &error = result.error();
return 1;
}
auto value = result.value();For status-returning operations:
auto status = auth.logout(session_id);
if (status.failed())
{
const auto &error = status.error();
return 1;
}Do not call .value() before checking ok() or failed().
What you should remember
Register a user:
auto registered = auth.register_user({"ada@example.com", "correct-password"});Login:
auto login = auth.login({"ada@example.com", "correct-password"});Authenticate the session:
auto session = auth.authenticate_session(login.value().session.id());Always check:
result.failed()before using:
result.value()Use memory auth for examples.
Use database auth for durable applications.
Next step
Learn password hashing directly.
Next: Password Hashing