mirror of
https://github.com/better-auth/better-auth.git
synced 2026-05-23 15:42:09 -05:00
docs: clarify verification storage for OTP flows (#8569)
Signed-off-by: Gautam Manchandani <manchandanigautam@gmail.com>
This commit is contained in:
committed by
GitHub
parent
d59923cf6c
commit
c2ee5520be
@@ -124,7 +124,7 @@ If you're using Cloudflare D1 with Drizzle or Prisma, use [`cloudflare:workers`]
|
||||
|
||||
## Secondary Storage
|
||||
|
||||
Secondary storage in Better Auth allows you to use key-value stores for managing session data, rate limiting counters, etc. This can be useful when you want to offload the storage of intensive records to a high performance storage or even RAM.
|
||||
Secondary storage in Better Auth allows you to use key-value stores for managing session data, verification records, rate limiting counters, and other short-lived auth data. This can be useful when you want to offload the storage of intensive records to a high performance storage or even RAM.
|
||||
|
||||
### Implementation
|
||||
|
||||
|
||||
@@ -532,7 +532,7 @@ these are options for OTP.
|
||||
default: 3,
|
||||
},
|
||||
storeOTP: {
|
||||
description: "How to store the otp in the database. Whether to store it as plain text, encrypted or hashed. You can also provide a custom encryptor or hasher.",
|
||||
description: "How to transform the stored OTP value, whether plain text, encrypted, or hashed. You can also provide a custom encryptor or hasher. The storage backend is controlled by the global verification config, so secondary storage can be used instead of the database.",
|
||||
type: "string",
|
||||
default: "plain",
|
||||
},
|
||||
|
||||
@@ -411,13 +411,13 @@ export const auth = betterAuth({
|
||||
|
||||
When the maximum attempts are exceeded, the `verifyOTP`, `signIn.emailOtp`, `verifyEmail`, and `resetPassword` methods will return an error with code `TOO_MANY_ATTEMPTS`.
|
||||
|
||||
- `storeOTP`: The method to store the OTP in your database, whether `encrypted`, `hashed` or `plain` text. Default is `plain` text.
|
||||
- `storeOTP`: The method used to transform the OTP before it is stored by Better Auth's verification layer, whether `encrypted`, `hashed` or `plain` text. Default is `plain` text.
|
||||
|
||||
<Callout>
|
||||
Note: This will not affect the OTP sent to the user, it will only affect the OTP stored in your database.
|
||||
Note: This will not affect the OTP sent to the user. It only affects the stored OTP value. The storage backend itself is controlled by the global [`verification`](/docs/reference/options#verification) config, so if you configure `secondaryStorage`, these verification records can live there instead of the database.
|
||||
</Callout>
|
||||
|
||||
Alternatively, you can pass a custom encryptor or hasher to store the OTP in your database.
|
||||
Alternatively, you can pass a custom encryptor or hasher to control how the stored OTP value is persisted.
|
||||
|
||||
**Custom encryptor**
|
||||
|
||||
|
||||
@@ -149,10 +149,12 @@ and a `ctx` context object as the second parameter.
|
||||
default, we return a long and cryptographically secure string.
|
||||
</Callout>
|
||||
|
||||
**storeToken**: The `storeToken` function is called to store the magic link token in the database. The default value is `"plain"`.
|
||||
**storeToken**: The `storeToken` function controls how the magic link token is transformed before it is stored by Better Auth's verification layer. The default value is `"plain"`.
|
||||
|
||||
The `storeToken` function can be one of the following:
|
||||
|
||||
- `"plain"`: The token is stored in plain text.
|
||||
- `"hashed"`: The token is hashed using the default hasher.
|
||||
- `{ type: "custom-hasher", hash: (token: string) => Promise<string> }`: The token is hashed using a custom hasher.
|
||||
|
||||
The storage backend itself is controlled by the global [`verification`](/docs/reference/options#verification) config. If you configure `secondaryStorage`, magic link verification records can be stored there instead of the database.
|
||||
|
||||
@@ -192,7 +192,7 @@ Read more about databases [here](/docs/concepts/database).
|
||||
|
||||
## `secondaryStorage`
|
||||
|
||||
Secondary storage configuration used to store session and rate limit data.
|
||||
Secondary storage configuration used to store session data, verification records, and rate limit data.
|
||||
|
||||
```ts
|
||||
import { betterAuth } from "better-auth";
|
||||
@@ -491,12 +491,13 @@ Verification configuration options.
|
||||
```ts
|
||||
import { betterAuth } from "better-auth";
|
||||
export const auth = betterAuth({
|
||||
secondaryStorage: {
|
||||
// your Redis or KV implementation
|
||||
},
|
||||
verification: {
|
||||
modelName: "verifications",
|
||||
fields: {
|
||||
userId: "user_id"
|
||||
},
|
||||
disableCleanup: false
|
||||
disableCleanup: false,
|
||||
storeIdentifier: "hashed",
|
||||
storeInDatabase: false
|
||||
},
|
||||
})
|
||||
```
|
||||
@@ -504,6 +505,10 @@ export const auth = betterAuth({
|
||||
- `modelName`: The model name for the verification table
|
||||
- `fields`: Map fields to different column names
|
||||
- `disableCleanup`: Disable cleaning up expired values when a verification value is fetched
|
||||
- `storeIdentifier`: How to store verification identifiers such as tokens and OTP keys. Supports `"plain"`, `"hashed"`, or a custom hasher. You can also use `{ default, overrides }` to apply different strategies per identifier prefix.
|
||||
- `storeInDatabase`: Store verification records in the database even when `secondaryStorage` is configured. Default is `false`.
|
||||
|
||||
If `secondaryStorage` is configured, verification records are stored there by default. That behavior applies to flows that use Better Auth's shared verification layer, including OTP and magic-link style flows.
|
||||
|
||||
## `rateLimit`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user