Password Hash
This example shows how to hash and verify passwords with rix/auth.
The example uses the public Rix facade:
#include <rix.hpp>and accesses password helpers through:
rix.auth.passwordUse this example when you want to hash a plain-text password and verify login attempts safely.
Create the file
mkdir -p ~/rix-auth-password-example
cd ~/rix-auth-password-example
touch password_hash.cppAdd:
#include <rix.hpp>
int main()
{
rix.debug.print("== rix/auth password hashing ==");
const auto password = "correct-password";
auto hashed = rix.auth.password.hash(password);
if (hashed.failed())
{
const auto &error = hashed.error();
rix.debug.eprint(
"auth error:",
rix.auth.error.to_string(error),
error.message());
return 1;
}
const bool valid = rix.auth.password.verify(
password,
hashed.value());
const bool invalid = rix.auth.password.verify(
"wrong-password",
hashed.value());
rix.debug.print("hash:", hashed.value());
rix.debug.print("valid password:", valid ? "yes" : "no");
rix.debug.print("wrong password:", invalid ? "yes" : "no");
if (!valid || invalid)
{
rix.debug.eprint("ERROR:", "password verification failed");
return 1;
}
rix.debug.print("OK:", "password verification successful");
return 0;
}Run it:
vix run password_hash.cppIf Rix is not available yet for single-file usage:
vix install -g rix/rix
vix run password_hash.cppExpected output shape:
== rix/auth password hashing ==
hash: ...
valid password: yes
wrong password: no
OK: password verification successfulThe exact hash value changes because password hashing uses a salt.
What this example does
The example defines a password:
const auto password = "correct-password";It hashes the password:
auto hashed = rix.auth.password.hash(password);It verifies the correct password:
const bool valid = rix.auth.password.verify(
password,
hashed.value());It verifies that a wrong password does not match:
const bool invalid = rix.auth.password.verify(
"wrong-password",
hashed.value());Hash a password
Use:
auto hashed = rix.auth.password.hash("correct-password");hash returns a result.
Check it before using the stored hash:
if (hashed.failed())
{
rix.debug.eprint(
"auth error:",
rix.auth.error.to_string(hashed.error()),
hashed.error().message());
return 1;
}Then use:
hashed.value()The value is an encoded password hash suitable for storage.
Do not store the plain-text password.
Verify a password
Use:
const bool ok = rix.auth.password.verify(
"correct-password",
hashed.value());If the password matches the hash, the result is true.
If it does not match, the result is false.
if (ok)
{
rix.debug.print("password accepted");
}Wrong password check
A wrong password should fail:
const bool wrong = rix.auth.password.verify(
"wrong-password",
hashed.value());
if (!wrong)
{
rix.debug.print("wrong password rejected");
}This is the expected behavior.
Result pattern
hash returns an auth result.
Use:
hashed.ok()
hashed.failed()
hashed.value()
hashed.error()Never call value() before checking success.
Wrong:
auto hashed = rix.auth.password.hash("correct-password");
rix.debug.print(hashed.value());Correct:
auto hashed = rix.auth.password.hash("correct-password");
if (hashed.failed())
{
return 1;
}
rix.debug.print(hashed.value());Password policy
Password hashing checks the configured password policy.
By default, the development configuration accepts passwords with a minimum length suitable for examples and local development.
This can fail:
auto hashed = rix.auth.password.hash("short");Handle the error:
if (hashed.failed())
{
rix.debug.eprint(
"auth error:",
rix.auth.error.to_string(hashed.error()),
hashed.error().message());
}Check whether a password is accepted
Use:
const bool accepted = rix.auth.password.accepts("correct-password");Example:
if (!rix.auth.password.accepts("short"))
{
rix.debug.eprint("password rejected by policy");
}accepts checks the length policy.
hash also checks the policy before creating a hash.
Use a custom configuration
You can hash and verify with a custom auth configuration.
auto config = rix.auth.config.development();
config.set_min_password_length(8);
config.set_password_hash_iterations(310000);
config.set_password_salt_size(16);
config.set_password_hash_size(32);
auto hashed = rix.auth.password.hash(
"correct-password",
config);Verify with the same style:
const bool ok = rix.auth.password.verify(
"correct-password",
hashed.value(),
config);Use custom configuration when your application needs stricter or different password policy settings.
Create a hasher
You can create a password hasher through the facade:
auto hasher = rix.auth.password.hasher();Then:
auto hashed = hasher.hash("correct-password");
const bool ok = hasher.verify(
"correct-password",
hashed.value());With configuration:
auto config = rix.auth.config.production();
auto hasher = rix.auth.password.hasher(config);For most examples, the facade helpers are enough:
rix.auth.password.hash(...)
rix.auth.password.verify(...)Complete custom policy example
#include <rix.hpp>
int main()
{
auto config = rix.auth.config.development();
config.set_min_password_length(12);
const auto password = "correct-password";
auto hashed = rix.auth.password.hash(
password,
config);
if (hashed.failed())
{
rix.debug.eprint(
"auth error:",
rix.auth.error.to_string(hashed.error()),
hashed.error().message());
return 1;
}
const bool ok = rix.auth.password.verify(
password,
hashed.value(),
config);
rix.debug.print("password valid:", ok ? "yes" : "no");
return ok ? 0 : 1;
}Run:
vix run password_hash.cppUse with registration
Normally, you do not need to call password hashing directly during registration.
auth.register_user hashes the password internally.
auto auth = rix.auth.memory();
auto registered = auth.register_user({
"ada@example.com",
"correct-password"});Use rix.auth.password.hash directly when you are writing lower-level auth utilities, tests, import tools, adapters, or custom flows.
Use with login
Normally, you do not need to call password verification directly during login.
auth.login verifies the password internally.
auto login = auth.login({
"ada@example.com",
"correct-password"});Use rix.auth.password.verify directly when testing, migrating stored hashes, or building custom auth flows.
Safe output
Do not print plain-text passwords.
Do not print password hashes in production logs.
This example prints the hash only to show that a hash was produced.
For real applications, store the hash and keep logs clean.
Use in a Vix project
Create a project:
vix new rix-auth-password --app
cd rix-auth-passwordAdd Rix:
vix add rix/rix
vix installMake sure vix.app contains:
deps = [
"rix/rix",
]A minimal vix.app can look like this:
name = "rix-auth-password"
type = "executable"
standard = "c++20"
output_dir = "bin"
sources = [
"src/main.cpp",
]
include_dirs = [
"include",
"src",
]
deps = [
"rix/rix",
]
packages = [
"vix",
]
links = [
"vix::vix",
]Put the example code in:
src/main.cppBuild and run:
vix build
vix runSingle-file usage
For examples, tests, and quick experiments:
vix run password_hash.cppIf needed:
vix install -g rix/rix
vix run password_hash.cppFor project usage, prefer:
vix add rix/rix
vix installand keep the dependency in vix.app:
deps = [
"rix/rix",
]Use only auth with the facade
If you want the rix.* facade style but only want auth mounted, define the feature macro before including rix.hpp:
#define RIX_ENABLE_AUTH
#include <rix.hpp>
int main()
{
auto hashed = rix.auth.password.hash("correct-password");
return hashed.ok() ? 0 : 1;
}When at least one RIX_ENABLE_* macro is defined, only selected modules are mounted.
If you also want debug output:
#define RIX_ENABLE_AUTH
#define RIX_ENABLE_DEBUG
#include <rix.hpp>
int main()
{
auto hashed = rix.auth.password.hash("correct-password");
if (hashed.failed())
{
rix.debug.eprint(
"auth error:",
rix.auth.error.to_string(hashed.error()),
hashed.error().message());
return 1;
}
rix.debug.print("hash created");
return 0;
}Use the independent package
For independent usage, install:
vix add rix/auth
vix installIn vix.app:
deps = [
"rix/auth",
]Then include auth package headers directly.
The examples in this documentation prefer the public facade:
#include <rix.hpp>and:
rix.authCommon mistakes
Forgetting to install Rix
If rix.hpp is not found, install Rix first.
For a project:
vix add rix/rix
vix installFor single-file usage:
vix install -g rix/rixPutting Rix in packages
Wrong:
packages = [
"rix/rix",
]Correct:
deps = [
"rix/rix",
]deps is for Vix Registry packages.
packages is for CMake package discovery.
Calling value() before checking success
Wrong:
auto hashed = rix.auth.password.hash("correct-password");
const auto &stored_hash = hashed.value();Correct:
auto hashed = rix.auth.password.hash("correct-password");
if (hashed.failed())
{
return 1;
}
const auto &stored_hash = hashed.value();Expecting the same hash every time
Password hashes include a salt.
This means hashing the same password twice can produce different encoded hashes.
That is expected.
Use verify to check whether a password matches a stored hash.
Logging passwords
Never log:
plain-text passwords
password hashes in productionFor docs, the hash may be printed to show the example result.
For production, do not print it.
Verifying against an empty hash
This returns false:
rix.auth.password.verify(
"correct-password",
"");Always store and pass the encoded hash returned by hash.
What you should remember
Hash a password:
auto hashed = rix.auth.password.hash("correct-password");Check the result:
if (hashed.failed())
{
rix.debug.eprint(
"auth error:",
rix.auth.error.to_string(hashed.error()),
hashed.error().message());
return 1;
}Verify the password:
const bool ok = rix.auth.password.verify(
"correct-password",
hashed.value());Wrong passwords return false:
const bool wrong = rix.auth.password.verify(
"wrong-password",
hashed.value());For project usage:
vix add rix/rix
vix installand keep:
deps = [
"rix/rix",
]Next step
Continue with session refresh and logout.