Basic Usage
Better Auth Ruby provides the same core server routes as upstream Better Auth:
- Email and password sign-up/sign-in
- Social OAuth sign-in and callbacks
- Session lookup, revocation, and sign-out
- Password reset and email verification
- User/account management routes
- Optional plugins for username, magic link, passkeys, organizations, admin, and more
Create The Auth Object
require "better_auth"
auth = BetterAuth.auth(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
base_url: ENV.fetch("BETTER_AUTH_URL", "http://localhost:3000"),
email_and_password: {
enabled: true
},
database: BetterAuth::Adapters::Memory.new
)Email And Password
Enable email and password auth with email_and_password.
auth = BetterAuth.auth(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
base_url: ENV.fetch("BETTER_AUTH_URL"),
email_and_password: {
enabled: true,
auto_sign_in: true
},
database: BetterAuth::Adapters::Postgres.new(
url: ENV.fetch("DATABASE_URL")
)
)Server-side calls use auth.api. Method names are Ruby snake_case versions of
the upstream endpoint keys.
result = auth.api.sign_up_email(
body: {
email: "ada@example.com",
password: "password123",
name: "Ada Lovelace"
}
)
token = result.fetch(:token)
user = result.fetch(:user)Sign in:
status, headers, body = auth.api.sign_in_email(
{
body: {
email: "ada@example.com",
password: "password123",
rememberMe: true
},
as_response: true
}
)as_response: true returns a Rack-style response tuple so callers can forward
Set-Cookie headers.
Sessions
Get the current session from cookies:
session = auth.api.get_session(
headers: {
"cookie" => request.env["HTTP_COOKIE"]
}
)
if session
current_user = session[:user]
endSign out:
status, headers, body = auth.api.sign_out(
{
headers: {
"cookie" => request.env["HTTP_COOKIE"]
},
as_response: true
}
)Social Sign-On
Configure providers under social_providers.
auth = BetterAuth.auth(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
base_url: ENV.fetch("BETTER_AUTH_URL"),
social_providers: {
github: BetterAuth::SocialProviders.github(
client_id: ENV.fetch("GITHUB_CLIENT_ID"),
client_secret: ENV.fetch("GITHUB_CLIENT_SECRET")
),
google: BetterAuth::SocialProviders.google(
client_id: ENV.fetch("GOOGLE_CLIENT_ID"),
client_secret: ENV.fetch("GOOGLE_CLIENT_SECRET")
)
}
)Start a social sign-in:
response = auth.api.sign_in_social(
body: {
provider: "github",
callbackURL: "/dashboard",
errorCallbackURL: "/login",
newUserCallbackURL: "/welcome",
disableRedirect: true
}
)
redirect_url = response.fetch(:url)Plugins
Plugins are passed as Ruby plugin objects.
auth = BetterAuth.auth(
secret: ENV.fetch("BETTER_AUTH_SECRET"),
base_url: ENV.fetch("BETTER_AUTH_URL"),
plugins: [
BetterAuth::Plugins.username,
BetterAuth::Plugins.magic_link(
send_magic_link: ->(email:, url:, token:, **) {
Mailer.magic_link(email, url).deliver_now
}
),
BetterAuth::Plugins.two_factor
]
)Plugin route paths match upstream Better Auth. Ruby method names on auth.api
are snake_case.
Rack Request Handling
auth is Rack-callable:
run authWhen mounted at /api/auth, requests such as POST /api/auth/sign-in/email
are handled by the Better Auth router.