
Product
Announcing Precomputed Reachability Analysis in Socket
Socket’s precomputed reachability slashes false positives by flagging up to 80% of vulnerabilities as irrelevant, with no setup and instant results.
@sidebase/nuxt-auth
Advanced tools
[![npm version][npm-version-src]][npm-version-href] [![npm downloads][npm-downloads-src]][npm-downloads-href] [](https://GitHub.com/sidebase/nuxt-auth/) [![License][license-src]][license-h
Nuxt user authentication and sessions via NextAuth.js.
nuxt-auth
wraps NextAuth.js to offer the reliability & convenience of a 12k star library to the nuxt 3 ecosystem with a native developer experience (DX).
npm i -D @sidebase/nuxt-auth
nuxt.config.ts
:
export default defineNuxtConfig({
modules: ['@sidebase/nuxt-auth'],
})
NuxtAuthHandler
) and add at least one authentication provider:
// file: ~/server/api/auth/[...].ts
import { NuxtAuthHandler } from '#auth'
import GithubProvider from 'next-auth/providers/github'
export default NuxtAuthHandler({
providers: [
// @ts-ignore Import is exported on .default during SSR, so we need to call it this way. May be fixed via Vite at some point
GithubProvider.default({ clientId: 'enter-your-client-id-here', clientSecret: 'enter-your-client-secret-here' })
]
})
[..].ts
is a catch-all route, see the nuxt server docs.vue
files):
const { status, data, signIn, signOut } = await useSession({
// Whether a session is required. If it is, a redirect to the signin page will happen if no active session exists
required: true
})
status.value // Session status: `unauthenticated`, `loading`, `authenticated`
data.value // Session data, e.g., expiration, user.email, ...
await signIn() // Sign in the user
await signOut() // Sign out the user
There's more supported methods in the useSession
composable, you can create client- and server-side authentication middlewares for your app and more - read the documentation below.
useSession
composable to: signIn
, signOut
, getCsrfToken
, getProviders
, getSession
GET /signin
,POST /signin/:provider
,GET/POST /callback/:provider
,GET /signout
,POST /signout
,GET /session
,GET /csrf
,GET /providers
nuxt-auth
is actively maintained. The goal of this library is to reach feature-parity with NextAuth.js
, see the current status below.
Visit the nuxt-auth
demo page here:
You can find the demo source-code here.
The nuxt-auth
module takes care of authentication and sessions:
username
. (Note: If you need only sessions but no authentication, you can check-out nuxt-session)In addition, you can use nuxt-auth
to build authorization on top of the supported authentication + session mechanisms: As soon as you know "whos who", you can use this information to let somebody with the right email adress (for example) into a specific area. Right now, this is not in-scope of nuxt-auth
itself.
If you want to have a more interactive introduction, check-out the demo page or the module playground.
Below we describe:
There's two places to configure nuxt-auth
:
auth
-key in nuxt.config.ts
: Configure the module itself, e.g., where the auth-endpoints are, what origin the app is deployed to, ...For development, you can stay with the Quick Start-configuration.
For a production deployment, you will have to at least set the:
origin
inside the nuxt.config.ts
config (equivalent to NEXTAUTH_URL
environment variable),secret
inside the NuxtAuthHandler
config (equivalent to NEXTAUTH_SECRET
environment variable)nuxt.config.ts
Use the auth
-key inside your nuxt.config.ts
to configure the module itself. Right now this is limited to the following options:
export default defineNuxtConfig({
modules: ['@sidebase/nuxt-auth'],
auth: {
// The module is enabled. Change this to disable the module
isEnabled: true,
// The origin is set to the development origin. Change this when deploying to production
origin: 'http://localhost:300',
// The base path to the authentication endpoints. Change this if you want to add your auth-endpoints at a non-default location
basePath: '/api/auth'
}
})
The origin
and the basePath
together are equivalent to the NEXTAUTH_URL
environment variable of NextAuth.js
You must set the origin
in production, this includes when you run npm run build
! This is so that nuxt-auth
can ensure that callbacks for authentication are correct. The origin
consists out of (up to) 3 parts:
http
or https
localhost
, example.org
, www.sidebase.io
:3000
, :4444
; leave empty to implicitly set :80
(this is an internet convention, don't ask)For the demo-app we set the origin
to https://nuxt-auth-example.sidebase.io
. If for some reason required, you can explicitly set the origin
to http://localhost:3000
to stop nuxt-auth
from aborting npm run build
when the origin is unset.
This is what tells the module where you added the authentication endpoints. Per default the basePath
is set to /api/auth
, so that means that the module expects that all requests to /api/auth/*
will be handled by the NuxtAuthHandler
.
To statify this, you need to create a catch-all server-route at that location by creating a file ~/server/api/auth/[...].ts
that exports the NuxtAuthHandler
, see more on this in the Quick Start or in the configuration section below.
If you want to have the authentication at another location, you can overwrite the basePath
, e.g., when setting:
basePath: "/api/_auth"
-> add the authentication catch-all endpoints into ~/server/api/_auth/[...].ts
basePath: "/_auth"
-> add the authentication catch-all endpoints into ~/server/routes/_auth/[...].ts
(see nuxt server-routes docs on this)Use the NuxtAuthHandler({ ... })
to configure how the authentication itself behaves:
// file: ~/server/api/auth/[...].ts
import { NuxtAuthHandler } from '#auth'
export default NuxtAuthHandler({
// your authentication configuration here!
})
The NuxtAuthHandler
accepts all options that NextAuth.js accepts for its API initialization. Use this place to configure authentication providers (oauth-google, credential flow, ...), your secret
(equivalent to NEXTAUTH_SECRET
in NextAuth.js), add callbacks for authentication events, configure a custom logger and more. Read the linked NextAuth.js
configuration to figure out how this works and what you can do.
Here's what a full config can look like, wee allow authentication via a:
CredentialsProvider
)Note that the below implementation of the credentials provider is flawd and mostly copied over from the NextAuth.js credentials example in order to give a picture of how to get started with the credentials provider:
// file: ~/server/api/auth/[...].ts
import CredentialsProvider from 'next-auth/providers/credentials'
import GithubProvider from 'next-auth/providers/github'
import { NuxtAuthHandler } from '#auth'
export default NuxtAuthHandler({
providers: [
// @ts-ignore Import is exported on .default during SSR, so we need to call it this way. May be fixed via Vite at some point
GithubProvider.default({
clientId: 'a-client-id',
clientSecret: 'a-client-secret'
})
// @ts-ignore Import is exported on .default during SSR, so we need to call it this way. 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: 'jsmith' },
password: { label: 'Password', type: 'password' }
},
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.
// e.g. return { id: 1, name: 'J Smith', email: 'jsmith@example.com' }
// You can also use the `req` object to obtain additional parameters
// (i.e., the request IP address)
// eslint-disable-next-line no-console
console.log('provided credentials: ', credentials)
const user = { id: '1', name: 'J Smith', email: 'jsmith@example.com' }
if (user) {
// Any object returned will be saved in `user` property of the JWT
return user
} else {
// If you return null then an error will be displayed advising the user to check their details.
return null
// 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
}
}
})
]
})
Note that there's way more options inside the nextAuth.options
object, see here for all available options.
This module allows you user-data access, signing in, signing out and more on the client-side via useSession
. It also allows you to defined middlewares that protects your page.
The useSession
composable is your main gateway to accessing and manipulating session-state and data. Here's the main methdos you can use:
const {
status,
data,
getCsrfToken,
getProviders,
getSession,
signIn,
signOut,
} = await useSession({
// Whether a session is required. If it is, a redirect to the signin page will happen if no active session exists
required: true
})
// Session status, either `unauthenticated`, `loading`, `authenticated`, see https://next-auth.js.org/getting-started/client#signout
status.value
// Session data, either `undefined` (= authentication not attempted), `null` (= user unauthenticated), `loading` (= session loading in progress), see https://next-auth.js.org/getting-started/client#signout
data.value
// Get / Reload the current session from the server, pass `{ required: true }` to force a login if no session exists, see https://next-auth.js.org/getting-started/client#getsession
await getSession()
// Get the current CSRF token, usually you do not need this function, see https://next-auth.js.org/getting-started/client#signout
await getCsrfToken()
// Get the supported providers, e.g., to build your own login page, see https://next-auth.js.org/getting-started/client#getproviders
await getProviders()
// Trigger a sign in, see https://next-auth.js.org/getting-started/client#signin
await signIn()
// Trigger a sign in with a redirect afterwards, see https://next-auth.js.org/getting-started/client#signin
await signIn(undefined, { callbackUrl: '/protected' })
// Trigger a sign in via a specific authentication provider with a redirect afterwards, see https://next-auth.js.org/getting-started/client#signin
await signIn('github', { callbackUrl: '/protected' })
// Trigger a sign out, see https://next-auth.js.org/getting-started/client#signout
await signOut()
Session data
has the following interface:
interface DefaultSession {
user?: {
name?: string | null;
email?: string | null;
image?: string | null;
};
expires: ISODateString;
}
Note that this is only set when the use is logged-in and when the provider used to login the user provides the fields.
You can also pass the callbackUrl
option to both the signIn
and the signOut
method. This allows you to redirect a user to a certain pages, after they've completed the action. This can be useful when a user attempts to open a page (/protected
) but has to go through external authentication (e.g., via their google account) first.
You can use it like:
await signIn({ callbackUrl: '/protected' })
to redirect the user to the protected page they wanted to access after they've been authenticated.
You can do the same for signing out the user:
await signOut({ callbackUrl: '/protected' })
E.g., here to redirect the user away from the already loaded, protected, page after signout (else, you will have to handle the redirect yourself).
You can use this library to define client-side middlewares. This library supports all of nuxt's supported approaches to define client-side middlewares, read on to learn how.
Create a global authentication middleware that ensures that your user is authenticated no matter which page they visit. For this create a file in the middlewares
directory that has a .global.ts
post-fix. It should look like this:
// file: ~/middlewares/auth.global.ts
import { defineNuxtRouteMiddleware } from '#app'
import useSession from '~/composables/useSession'
export default defineNuxtRouteMiddleware(async () => {
await useSession()
})
That's it! This middleware will fetch a session and if no active session exists for the current user redirect to the login screen. If you want to write custom redirect logic, you could alter the above code to only apply to specific routes. Here is a global middleware that protects only the routes that start with /secret/
:
// file: ~/middlewares/auth.global.ts
import { defineNuxtRouteMiddleware } from '#app'
import useSession from '~/composables/useSession'
export default defineNuxtRouteMiddleware(async (to) => {
if (!to.path.startsWith('/secret/')) {
return
}
await useSession()
})
Here's a middleware that redirects to a custom login page:
// file: ~/middlewares/auth.global.ts
import { defineNuxtRouteMiddleware, navigateTo } from '#app'
import useSession from '~/composables/useSession'
export default defineNuxtRouteMiddleware(async (to) => {
// 1. Always allow access to the login page
if (to.path === '/login') {
return
}
// 2. Otherwise: Check status and redirect to login page
const { status } = await useSession({ required: false })
if (status.value !== 'authenticated') {
navigateTo('/login')
}
})
Named middlewares behave similar to global middlewares but are not automatically applied to any pages.
To use them, first create a middleware:
// file: ~/middlewares/auth.ts
import { defineNuxtRouteMiddleware } from '#app'
import useSession from '~/composables/useSession'
export default defineNuxtRouteMiddleware(async () => {
await useSession()
})
Note that there's no .global.ts
postfix in the filename above! Then inside your pages use this middleware like this:
<!-- file: ~/pages/protected.vue -->
<template>
<div>I'm a secret!</div>
</template>
<script setup lang="ts">
definePageMeta({
middleware: ['auth']
})
</script>
Note: definePageMeta
can only be used inside the pages/
directory!
Nuxt now calls the auth.ts
middleware on every visit to this page.
To define a named middleware, you need to use definePageMeta
as described in the nuxt docs. Then you can just call useSession
as in the other middlewares. Here's an example that would protect just the page itself:
<!-- file: ~/pages/protected.vue -->
<template>
<div>I'm a secret!</div>
</template>
<script setup lang="ts">
definePageMeta({
middleware: async () => {
await useSession()
}
})
</script>
Note: definePageMeta
can only be used inside the pages/
directory!
On the server side you can get access to the current session like this:
import { getServerSession } from '#auth'
export default eventHandler(async (event) => {
const session = await getServerSession(event)
})
This is inspired by the getServerSession of NextAuth.js. It also avoids an external, internet call to the GET /api/auth/sessions
endpoint, instead directly calling a pure JS-method.
To protect an endpoint with, check the session after fetching it:
// file: ~/server/api/protected.get.ts
import { getServerSession } from '#auth'
export default eventHandler(async (event) => {
const session = await getServerSession(event)
if (!session) {
return { status: 'unauthenticated!' }
}
return { status: 'authenticated!' }
})
You can also use this in a nuxt server middleware to protect multiple pages at once and keep the authentication logic out of your endpoints:
// file: ~/server/middleware/auth.ts
import { getServerSession } from '#auth'
export default eventHandler(async (event) => {
const session = await getServerSession(event)
if (!session) {
throw createError({ statusMessage: 'Unauthenticated', statusCode: 403 })
}
})
All endpoints that NextAuth.js supports are also supported by nuxt-auth
:
GET /signin
,POST /signin/:provider
,GET/POST /callback/:provider
,GET /signout
,POST /signout
,GET /session
,GET /csrf
,GET /providers
You can directly interact with them if you wish to, it's probably a better idea to use useSession
where possible though. See the full rest API documentation of NextAuth.js here.
The idea of this library is to re-use all the open-source implementation that already exist in the JS ecosystem instead of rolling our own. The idea was born when researching through the ecosystem of framework-specific authentication libraries to figure out what the best implementation approach for a state-of-the-art nuxt 3 authentication library would be.
During research it became clear that implementing everything from scratch will be:
In order to avoid these problems without taking forever (leaving nuxt without an authentication library in the meantime), we decided to investigate if we can wrap NextAuth.js
, the most popular authentication library in the Next.js ecosystem by far and a trusted, well maintained one at that!
In our investigation we found prior attempts to make NextAuth.js framework agnostic. These have more or less come to fruition, so far mostly resulting in some PoCs and example apps. Looking at these was quite helpful to get started. In particular, big pushes in the right direction came from:
The main part of the work was to piece everything together, resolve some outstanding issues with existing PoCs, add new things where nothing existed yet, e.g., for the client useSession
composable by going through the NextAuth.js client code and translating it to a nuxt 3 approach.
🚧 This project is under active development: A lot of stuff already works and as NextAuth.js handles the authentication under the hood, the module should already be ready for most use-cases. Still, some functionality is missing, e.g., we've focused on oauth-providers in the first implementation, so the credential- and email-flow are untested.
Roughly, the roadmap of nuxt-auth
is:
local
/ credentials
flow than NextAuth.js does out of the box (they don't do it for good reasons, so, there really is an honest discussion to be had), adding more UI focused components that automatically and easily wrap your app in a nice auth page, ...We also want to listen to all suggestions, feature requests, bug reports, ... from you. So if you have any ideas, please open an issue or reach out to us on Twitter or via E-Mail.
This module also has it's own playground, you can also use that to get familiar with it and play around a bit:
> git clone https://github.com/sidebase/nuxt-auth
> cd nuxt-auth
# **OPEN THE `~/playground/server/api/auth/[...].ts` and configure your own auth-provider
> npm i
> npm run dev:prepare
> npm run dev
# -> open http://localhost:3000
Note: The playground has considerably less polishing than the example page.
npm run dev:prepare
to generate type stubs.npm run dev
to start the module playground in development mode.npm run lint
to run eslintnpm run type
to run typescheck via tscnpm publish --access public
to publish (bump version before)FAQs
Authentication built for Nuxt 3! Easily add authentication via OAuth providers, credentials or Email Magic URLs!
The npm package @sidebase/nuxt-auth receives a total of 19,693 weekly downloads. As such, @sidebase/nuxt-auth popularity was classified as popular.
We found that @sidebase/nuxt-auth demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Socket’s precomputed reachability slashes false positives by flagging up to 80% of vulnerabilities as irrelevant, with no setup and instant results.
Product
Socket is launching experimental protection for Chrome extensions, scanning for malware and risky permissions to prevent silent supply chain attacks.
Product
Add secure dependency scanning to Claude Desktop with Socket MCP, a one-click extension that keeps your coding conversations safe from malicious packages.