mirror of
https://github.com/better-auth/better-auth.git
synced 2026-05-30 02:46:44 -05:00
* refactor * cleanup and more refactor * test: cli * chore: release v0.4.9-beta.12 * feat: kysley generate and orm migrations * chore: release v0.4.9-beta.13 * test: generate * test: change test snapshot file * docs * chore: lint * fix: test * chore: release v0.4.9-beta.14 * chore: release v0.4.9
468 lines
14 KiB
Plaintext
468 lines
14 KiB
Plaintext
---
|
|
title: Basic Usage
|
|
description: Getting started with Better Auth
|
|
---
|
|
|
|
Better Auth provides built-in authentication support for:
|
|
|
|
- **Email and password**
|
|
- **Social provider (Google, Github, Apple, and more)**
|
|
|
|
<Callout>
|
|
You can extend authentication options using plugins, such as: Username-based login, Passkeys, Email magic links, and more.
|
|
</Callout>
|
|
|
|
## Email & Password
|
|
|
|
To enable email and password authentication:
|
|
|
|
```ts title="auth.ts"
|
|
import { betterAuth } from "better-auth"
|
|
|
|
export const auth = betterAuth({
|
|
//...rest of the options
|
|
emailAndPassword: { // [!code highlight]
|
|
enabled: true // [!code highlight]
|
|
} // [!code highlight]
|
|
})
|
|
```
|
|
|
|
### Signup
|
|
|
|
Before a user can sign in, they need to sign up. To sign up a user using email and password, you need to call the client method `signUp.email` with the user's information.
|
|
|
|
You can pass the following properties to the `signUp.email` method:
|
|
|
|
- **email**: the user's email address
|
|
- **password**: the user's password
|
|
- **name**: the user's display name
|
|
- **image**: the user's image url (optional)
|
|
|
|
**Example: Using React**
|
|
|
|
```tsx title="SignUp.tsx"
|
|
"use client"
|
|
import { authClient } from "@/lib/auth-client"; //import the auth client // [!code highlight]
|
|
import { useState } from 'react';
|
|
|
|
export default function SignUp() {
|
|
const [email, setEmail] = useState('');
|
|
const [password, setPassword] = useState('');
|
|
const [name, setName] = useState('');
|
|
const [image, setImage] = useState<File | null>(null);
|
|
|
|
const signUp = async () => {
|
|
const { data, error } = await authClient.signUp.email({ // [!code highlight]
|
|
email, // [!code highlight]
|
|
password, // [!code highlight]
|
|
name, // [!code highlight]
|
|
image: image ? convertImageToBase64(image) : undefined, // [!code highlight]
|
|
}, { // [!code highlight]
|
|
onRequest: (ctx) => { // [!code highlight]
|
|
//show loading // [!code highlight]
|
|
}, // [!code highlight]
|
|
onSuccess: (ctx) => { // [!code highlight]
|
|
//redirect to the dashboard // [!code highlight]
|
|
}, // [!code highlight]
|
|
onError: (ctx) => { // [!code highlight]
|
|
alert(ctx.error.message); // [!code highlight]
|
|
}, // [!code highlight]
|
|
}); // [!code highlight]
|
|
};
|
|
|
|
return (
|
|
<div>
|
|
<input type="name" value={email} onChange={(e) => setName(e.target.value)} />
|
|
<input type="password" value={password} onChange={(e) => setPassword(e.target.value)} />
|
|
<input type="email" value={email} onChange={(e) => setEmail(e.target.value)} />
|
|
<input type="file" onChange={(e) => setImage(e.target.files?.[0])} />
|
|
<button onClick={signUp}>Sign Up</button>
|
|
</div>
|
|
);
|
|
}
|
|
```
|
|
|
|
### Signin
|
|
|
|
To signin a user, you can use the `signIn.email` function provided by the client. The `signIn` function takes an object with the following properties:
|
|
|
|
- **email**: the user's email address
|
|
- **password**: the user's password
|
|
|
|
**Example: Using Svelte**
|
|
|
|
```svelte title="signin.svelte"
|
|
<script lang="ts">
|
|
import { authClient } from "$lib/auth-client"; //import the auth client // [!code highlight]
|
|
import { writable } from "svelte/store";
|
|
|
|
const email = writable("");
|
|
const password = writable("");
|
|
|
|
const handleSignIn = async () => {
|
|
await authClient.signIn.email({ // [!code highlight]
|
|
email: $email, // [!code highlight]
|
|
password: $password, // [!code highlight]
|
|
}, { // [!code highlight]
|
|
onRequest: () => { // [!code highlight]
|
|
//show loading // [!code highlight]
|
|
}, // [!code highlight]
|
|
onSuccess: () => { // [!code highlight]
|
|
//redirect to dashboard // [!code highlight]
|
|
}, // [!code highlight]
|
|
onError: (ctx) => { // [!code highlight]
|
|
alert(ctx.error.message) // [!code highlight]
|
|
} // [!code highlight]
|
|
}) // [!code highlight]
|
|
}
|
|
</script>
|
|
|
|
<div>
|
|
<input type="email" bind:value={$email} />
|
|
<input type="password" bind:value={$password} />
|
|
<button on:click={handleSignIn}>
|
|
Sign In
|
|
</button>
|
|
</div>
|
|
```
|
|
|
|
## Social Sign-On
|
|
|
|
Better Auth supports multiple social providers, including Google, Github, Apple, Discord, and more. To use a social provider, you need to configure the ones you need in the `socialProviders` option on your `auth` object.
|
|
|
|
```ts title="auth.ts"
|
|
import { betterAuth } from "better-auth"
|
|
import { github } from "better-auth/social-providers"
|
|
|
|
export const auth = betterAuth({
|
|
//...rest of the options
|
|
socialProviders: { // [!code highlight]
|
|
github: { // [!code highlight]
|
|
clientId: process.env.GITHUB_CLIENT_ID!, // [!code highlight]
|
|
clientSecret: process.env.GITHUB_CLIENT_SECRET!, // [!code highlight]
|
|
} // [!code highlight]
|
|
}, // [!code highlight]
|
|
})
|
|
```
|
|
|
|
### Signin with social providers
|
|
|
|
To sign in using a social provider you need to call `signIn.social` method and pass the `provider`.
|
|
|
|
It also takes `callbackURL` property which is the url the user will be redirected after they signIn.
|
|
|
|
**Example: Using Vue**
|
|
|
|
```vue title="signin.vue"
|
|
<script>
|
|
import { authClient } from "@/auth-client"; //import the auth client // [!code highlight]
|
|
|
|
export default {
|
|
name: "SignIn",
|
|
methods: {
|
|
async handleSignIn() {
|
|
await authClient.signIn.social({ // [!code highlight]
|
|
provider: "github", // [!code highlight]
|
|
callbackURL: "/dashboard", //redirect to dashboard after sign in // [!code highlight]
|
|
}); // [!code highlight]
|
|
}
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<h2>Sign In</h2>
|
|
<button @click="handleSignIn">Sign In with GitHub</button>
|
|
</div>
|
|
</template>
|
|
```
|
|
|
|
## Session Management
|
|
|
|
Once a user is signed in, you'll want to access their session. Better Auth allows you easily to access the session data from the server and client side.
|
|
|
|
### Client Side
|
|
|
|
Better Auth provides a `useSession` hook to easily access session data on the client side. This hook is implemented in a reactive way for each supported framework, ensuring that any changes to the session (such as signing out) are immediately reflected in your UI.
|
|
|
|
It has the following properties:
|
|
- **data**: the actual session data which includes `session` and `user` object.
|
|
- **isPending**: a boolean that indicates whether the session is being loaded.
|
|
- **error**: an error object that contains any errors that occurred while loading the session.
|
|
|
|
<Tabs items={["React", "Vue","Svelte", "Solid", "Vanilla"]} defaultValue="React">
|
|
<Tab value="React">
|
|
```tsx title="user.tsx"
|
|
import { authClient } from "@/lib/auth-client" // import the auth client // [!code highlight]
|
|
|
|
export function User(){
|
|
|
|
const { // [!code highlight]
|
|
data: session, // [!code highlight]
|
|
isPending, //loading state // [!code highlight]
|
|
error //error object // [!code highlight]
|
|
} = authClient.useSession() // [!code highlight]
|
|
|
|
return (
|
|
//...
|
|
)
|
|
}
|
|
```
|
|
</Tab>
|
|
|
|
<Tab value="Vue">
|
|
```vue title="index.vue"
|
|
<script setup lang="ts">
|
|
import { authClient } from "~/lib/auth-client" // [!code highlight]
|
|
|
|
const session = authClient.useSession() // [!code highlight]
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<div>
|
|
<pre>{{ session.data }}</pre>
|
|
<button v-if="session.data" @click="authClient.signOut()">
|
|
Sign out
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
```
|
|
</Tab>
|
|
|
|
<Tab value="Svelte">
|
|
```svelte title="user.svelte"
|
|
<script lang="ts">
|
|
import { authClient } from "$lib/auth-client"; // [!code highlight]
|
|
|
|
const session = authClient.useSession(); // [!code highlight]
|
|
</script>
|
|
<p>
|
|
{$session.data?.user.email}
|
|
</p>
|
|
```
|
|
</Tab>
|
|
<Tab value="Vanilla">
|
|
```ts title="user.svelte"
|
|
import { authClient } from "~/lib/auth-client"; //import the auth client
|
|
|
|
authClient.useSession.subscribe((value)=>{
|
|
//do something with the session //
|
|
})
|
|
```
|
|
</Tab>
|
|
|
|
<Tab value="Solid">
|
|
```tsx title="user.tsx"
|
|
import { authClient } from "~/lib/auth-client"; // [!code highlight]
|
|
|
|
export default function Home() {
|
|
const session = authClient.useSession() // [!code highlight]
|
|
return (
|
|
<pre>{JSON.stringify(session(), null, 2)}</pre>
|
|
);
|
|
}
|
|
```
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
<Callout>
|
|
For more details check [session-management](/docs/concepts/session-management) documentation.
|
|
</Callout>
|
|
|
|
### Server Side
|
|
|
|
The server provides a `session` object that you can use to access the session data. It requires request headers object to be passed to the `getSession` method.
|
|
|
|
**Example: Using some popular frameworks**
|
|
|
|
<Tabs items={["NextJs", "Nuxt", "Svelte", "Astro", "Hono"]}>
|
|
<Tab value="NextJs">
|
|
```ts title="server.ts"
|
|
import { auth } from "./auth"; // path to your Better Auth server instance
|
|
import { headers } from "next/headers";
|
|
|
|
const session = await auth.api.getSession({
|
|
headers: headers() // you need to pass the headers object.
|
|
})
|
|
```
|
|
</Tab>
|
|
<Tab value="Remix">
|
|
```ts title="route.ts"
|
|
import { auth } from "lib/auth"; // path to your Better Auth server instance
|
|
|
|
export async function loader({ request }: LoaderFunctionArgs) {
|
|
const session = await auth.api.getSession({
|
|
headers: request.headers
|
|
})
|
|
|
|
return json({ session })
|
|
}
|
|
```
|
|
</Tab>
|
|
<Tab value="Astro">
|
|
```astro title="index.astro"
|
|
---
|
|
import { auth } from "./auth";
|
|
|
|
const session = await auth.api.getSession({
|
|
headers: Astro.request.headers,
|
|
});
|
|
---
|
|
<!-- Your Astro Template -->
|
|
```
|
|
</Tab>
|
|
<Tab value="Svelte">
|
|
```ts title="+page.ts"
|
|
import { auth } from "./auth";
|
|
|
|
export async function load({ request }) {
|
|
const session = await auth.api.getSession({
|
|
headers: request.headers
|
|
})
|
|
return {
|
|
props: {
|
|
session
|
|
}
|
|
}
|
|
}
|
|
```
|
|
</Tab>
|
|
<Tab value="Hono">
|
|
```ts title="index.ts"
|
|
import { auth } from "./auth";
|
|
|
|
const app = new Hono();
|
|
|
|
app.get("/path", async (c) => {
|
|
const session = auth.api.getSession({
|
|
headers: c.req.raw.headers
|
|
})
|
|
});
|
|
```
|
|
</Tab>
|
|
|
|
<Tab value="Nuxt">
|
|
```ts title="server/session.ts"
|
|
import { auth } from "~/utils/auth";
|
|
|
|
export default defineEventHandler((event) => {
|
|
const session = await auth.api.getSession({
|
|
headers: event.headers,
|
|
})
|
|
});
|
|
```
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
## Using Plugins
|
|
|
|
One of the unique features of Better Auth is a plugins ecosystem. It allows you to add complex auth realted functionilty with small lines of code.
|
|
|
|
Below is an example of how to add two factor authentication using two factor plugin.
|
|
|
|
<Steps>
|
|
|
|
<Step>
|
|
### Server Configuration
|
|
|
|
To add a plugin, you need to import the plugin and pass it to the `plugins` option of the auth instance. For example, to add two facor authentication, you can use the following code:
|
|
|
|
```ts title="auth.ts"
|
|
import { betterAuth } from "better-auth"
|
|
import { twoFactor } from "better-auth/plugins" // [!code highlight]
|
|
|
|
export const auth = betterAuth({
|
|
//...rest of the options
|
|
plugins: [ // [!code highlight]
|
|
twoFactor() // [!code highlight]
|
|
] // [!code highlight]
|
|
})
|
|
```
|
|
now two factor related routes and method will be available on the server.
|
|
|
|
</Step>
|
|
<Step>
|
|
### Migrate Database
|
|
|
|
After adding the plugin, you'll need to add the required tables to your database. You can do this by running the `migrate` command, or by using the `generate` command to create the schema and handle the migration manually.
|
|
|
|
generating the schema:
|
|
|
|
```bash title="terminal"
|
|
npx @better-auth/cli generate
|
|
```
|
|
|
|
using the `migrate` command:
|
|
|
|
```bash title="terminal"
|
|
npx @better-auth/cli migrate
|
|
```
|
|
|
|
<Callout>
|
|
If you prefer adding the schema manually, you can check the schema required on the [two factor plugin](/docs/plugins/2fa#schema) documentation.
|
|
</Callout>
|
|
|
|
</Step>
|
|
<Step>
|
|
### Client Configuration
|
|
|
|
Once we're done with the server, we need to add the plugin to the client. To do this, you need to import the plugin and pass it to the `plugins` option of the auth client. For example, to add two facor authentication, you can use the following code:
|
|
|
|
```ts title="client.ts" /
|
|
import { createAuthClient } from "better-auth/client";
|
|
import { twoFactorClient } from "better-auth/client/plugins"; // [!code highlight]
|
|
|
|
const authClient = createAuthClient({
|
|
plugins: [ // [!code highlight]
|
|
twoFactorClient({ // [!code highlight]
|
|
twoFactorPage: "/two-factor" // the page to redirect if a user need to verify 2nd factor // [!code highlight]
|
|
}) // [!code highlight]
|
|
] // [!code highlight]
|
|
})
|
|
```
|
|
|
|
now two factor related methods will be available on the client.
|
|
|
|
```ts title="profile.ts"
|
|
import { authClient } from "./auth-client"
|
|
|
|
const enableTwoFactor = async() => {
|
|
const data = await authClient.twoFactor.enable({
|
|
password // the user password is required
|
|
}) // this will enable two factor
|
|
}
|
|
|
|
const disableTwoFactor = async() => {
|
|
const data = await authClient.twoFactor.disable({
|
|
password // the user password is required
|
|
}) // this will disable two factor
|
|
}
|
|
|
|
const signInWith2Factor = async() => {
|
|
const data = await authClient.signIn.email({
|
|
//...
|
|
})
|
|
//if the user has two factor enabled, it will redirect to the two factor page
|
|
}
|
|
|
|
const verifyTOTP = async() => {
|
|
const data = await authClient.twoFactor.verifyTOTP({
|
|
code: "123456", // the code entered by the user
|
|
/**
|
|
* If the device is trusted, the user won't
|
|
* need to pass 2FA again on the same device
|
|
*/
|
|
trustDevice: true
|
|
})
|
|
}
|
|
```
|
|
</Step>
|
|
|
|
<Step>
|
|
Next step: See the <Link href="/docs/plugins/2fa">the two factor plugin documentation</Link>.
|
|
</Step>
|
|
</Steps>
|