providers/credentials
default()β
default<CredentialsInputs>(config): CredentialsConfig
The Credentials provider allows you to handle signing in with arbitrary credentials, such as a username and password, domain, or two factor authentication or hardware device (e.g. YubiKey U2F / FIDO).
It is intended to support use cases where you have an existing system you need to authenticate users against.
It comes with the constraint that users authenticated in this manner are not persisted in the database, and consequently that the Credentials provider can only be used if JSON Web Tokens are enabled for sessions.
The functionality provided for credentials-based authentication is intentionally limited to discourage the use of passwords due to the inherent security risks of the username-password model.
OAuth providers spend significant amounts of money, time, and engineering effort to build:
- abuse detection (bot-protection, rate-limiting)
- password management (password reset, credential stuffing, rotation)
- data security (encryption/salting, strength validation)
and much more for authentication solutions. It is likely that your application would benefit from leveraging these battle-tested solutions rather than try to rebuild them from scratch.
If you'd still like to build password-based authentication for your application despite these risks, Auth.js gives you full control to do so.
See the callbacks documentation for more information on how to interact with the token. For example, you can add additional information to the token by returning an object from the jwt()
callback:
callbacks: {
async jwt({ token, user, account, profile, isNewUser }) {
if (user) {
token.id = user.id
}
return token
}
}
Type parametersβ
βͺ CredentialsInputs extends Record
< string
, CredentialInput
> = Record
< string
, CredentialInput
>
Parametersβ
βͺ config: Partial
< CredentialsConfig
< CredentialsInputs
> >
Returnsβ
Exampleβ
import Auth from "@auth/core"
import Credentials from "@auth/core/providers/credentials"
const request = new Request("https://example.com")
const response = await AuthHandler(request, {
providers: [
Credentials({
credentials: {
username: { label: "Username" },
password: { label: "Password", type: "password" }
},
async authorize({ request }) {
const response = await fetch(request)
if(!response.ok) return null
return await response.json() ?? null
}
})
],
secret: "...",
trustHost: true,
})
Seeβ
CredentialInputβ
Besides providing type safety inside CredentialsConfig.authorize it also determines how the credentials input fields will be rendered on the default sign in page.
Extendsβ
Partial
<JSX.IntrinsicElements
["input"
] >
CredentialsConfig<CredentialsInputs>β
The Credentials Provider needs to be configured.
Extendsβ
Type parametersβ
βͺ CredentialsInputs extends Record
< string
, CredentialInput
> = Record
< string
, CredentialInput
>
Propertiesβ
authorizeβ
authorize: (credentials, request) => Awaitable< null | User >;
Gives full control over how you handle the credentials received from the user.
There is no validation on the user inputs by default, so make sure you do so by a popular library like Zod
This method expects a User
object to be returned for a successful login.
If an CredentialsSignin
is thrown or null
is returned, two things can happen:
- The user is redirected to the login page, with
error=CredentialsSignin&code=credentials
in the URL.code
is configurable, see below. - If you throw this error in a framework that handles form actions server-side, this error is thrown by the login form action, so you'll need to handle it there.
In case of 1., generally, we recommend not hinting if the user for example gave a wrong username or password specifically, try rather something like "invalid-credentials". Try to be as generic with client-side errors as possible.
To customize the error code, you can create a custom error that extends CredentialsSignin and throw it in authorize
.
Parametersβ
βͺ credentials: Partial
< Record
< keyof CredentialsInputs
, unknown
> >
The available keys are determined by CredentialInput.
Note
The existence/correctness of a field cannot be guaranteed at compile time, so you should always validate the input before using it.
You can add basic validation depending on your use case, or you can use a popular library like Zod for example.
βͺ request: Request
The original request.
Returnsβ
Awaitable
< null
| User
>
Exampleβ
class CustomError extends CredentialsSignin {
code = "custom_error"
}
// URL will contain `error=CredentialsSignin&code=custom_error`
Exampleβ
async authorize(credentials, request) { // you have access to the original request as well
if(!isValidCredentials(credentials)) {
throw new CustomError()
}
return await getUser(credentials) // assuming it returns a User or null
}
idβ
id: string;
Uniquely identifies the provider in AuthConfig.providers It's also part of the URL
Inherited fromβ
providers.CommonProviderOptions.id
nameβ
name: string;
The provider name used on the default sign-in page's sign-in button. For example if it's "Google", the corresponding button will say: "Sign in with Google"