In order to create your own NuxtAuthHandler, create the file ~/server/api/auth/[...].ts. This file will automatically set up the authentication API that responds to all requests going to https://localhost/api/auth/*. If you wish you can also use a custom file location and api path, however this change will need to be reflected in the basePath, which is configured in the nuxt.config.ts.
The filename must be [...].ts - this is a so-called "catch-all" route, read more in the Nuxt catch-all docs.
After creating the file, add the NuxtAuthHandler({ ... }) to it. The NuxtAuthHandler({ ... }) is used to configure how the authentication itself behaves, what callbacks should be called, what database adapters should be used and more:
// file: ~/server/api/auth/[...].tsimport GithubProvider from'next-auth/providers/github'import { NuxtAuthHandler } from'#auth'exportdefaultNuxtAuthHandler({// A secret string you define, to ensure correct encryptionsecret: 'your-secret-here',providers: [// @ts-expect-error You need to use .default here for it to work during SSR. May be fixed via Vite at some point GithubProvider.default({ clientId: 'your-client-id', clientSecret: 'your-client-secret' }) ]})
NuxtAuthHandler with Credentials Provider
// file: ~/server/api/auth/[...].tsimport CredentialsProvider from'next-auth/providers/credentials'import { NuxtAuthHandler } from'#auth'exportdefaultNuxtAuthHandler({// A secret string you define, to ensure correct encryptionsecret: 'your-secret-here',providers: [// @ts-expect-error You need to use .default here for it to work during SSR. May be fixed via Vite at some point CredentialsProvider.default({// The name to display on the sign in form (e.g. 'Sign in with...') name: 'Credentials',// The credentials is used to generate a suitable form on the sign in page.// You can specify whatever fields you are expecting to be submitted.// e.g. domain, username, password, 2FA token, etc.// You can pass any HTML attribute to the <input> tag through the object. credentials: { username: { label: 'Username', type: 'text', placeholder: '(hint: jsmith)' }, password: { label: 'Password', type: 'password', placeholder: '(hint: hunter2)' } },authorize (credentials:any) {// You need to provide your own logic here that takes the credentials// submitted and returns either a object representing a user or value// that is false/null if the credentials are invalid.// NOTE: THE BELOW LOGIC IS NOT SAFE OR PROPER FOR AUTHENTICATION!constuser= { id: '1', name: 'J Smith', username: 'jsmith', password: 'hunter2' }if (credentials?.username === user.username && credentials?.password === user.password) {// Any object returned will be saved in `user` property of the JWTreturn user } else {// eslint-disable-next-line no-console console.error('Warning: Malicious login attempt registered, bad credentials provided')// If you return null then an error will be displayed advising the user to check their details.returnnull// You can also Reject this callback with an Error thus the user will be sent to the error page with the error message as a query parameter } } }) ]})
In theory the only required configuration key for production is the secret. You can set it directly inside the NuxtAuthHandler. In practice however you may also want to configure at least one provider so that your users can actually login.
To avoid hard-coding of the secret you can make it configurable at runtime by using an environment variable and exporting it at runtime or by using the nuxt runtimeconfig (and then also setting the correct environment at runtime):
Environment Variable
// file: ~/server/api/auth/[...].tsimport { NuxtAuthHandler } from'#auth'exportdefaultNuxtAuthHandler({// A secret string you define, to ensure correct encryption - required in productionsecret: process.env.AUTH_SECRET// rest of your authentication configuration here!})
useRuntimeConfig
// file: ~/server/api/auth/[...].tsimport { NuxtAuthHandler } from'#auth'exportdefaultNuxtAuthHandler({// A secret string you define, to ensure correct encryption - required in productionsecret: useRuntimeConfig().authSecret// rest of your authentication configuration here!})