nuxt-auth

repository·main·Indexed 23 days ago

https://github.com/sidebase/nuxt-auth

A comprehensive authentication library for Nuxt 3+ applications. It supports OAuth/Auth.js flows for non-static apps and local credential-based flows for static sites. Key features include the useAuth composable for session management, application and server-side protection middleware, customizable session refresh behavior, and server-side utilities like getServerSession and getToken.

Tokens
32.3K
Snippets
85
Records
146
Agent score
75%

What's inside @sidebase/nuxt-auth

  1. Overview of NuxtAuth features

    main

    NuxtAuth is a Nuxt 3+ module that provides authentication by integrating directly into the Nuxt ecosystem. It allows you to access user sessions within pages, components, and composables.

    Key capabilities include:

    Authentication Providers

    • OAuth: Support for providers like GitHub, Google, Twitter, Azure, etc.
    • Custom OAuth: Ability to add your own OAuth providers.
    • Credentials: Username/email and password authentication.
    • Email Magic URLs: Passwordless authentication via email.

    Application Side Session Management

    • Session fetching with status, data, and lastRefreshedAt.
    • Built-in methods for getSession, getCsrfToken, getProviders, signIn, and signOut.
    • Full TypeScript support.

    Application Protection

    • Client-side: Middleware protection for the entire application or specific routes.
    • Server-side: Middleware and endpoint protection.
  2. Configure session refresh behavior

    main

    You can manage the session lifecycle using customizable refresh behavior. This can be configured via the RefreshHandler to:

    • Refresh the session periodically.
    • Refresh the session when a tab regains focus.
    • Perform a one-time session fetch on page load, followed by fetches triggered by specific actions like navigation.
  3. Understand the relationship between NuxtAuth and Auth.js/NextAuth

    main

    NuxtAuth uses Auth.js / NextAuth.js as its underlying engine via the authjs provider. This allows NuxtAuth to leverage a massive ecosystem of OAuth providers, database adapters, and callbacks while providing a native Nuxt developer experience (DX).

    Key implications for developers:

    • Documentation: You can use official Auth.js and NextAuth.js guides and documentation to configure the authjs provider in NuxtAuth.
    • Terminology: The terms authjs and next-auth are used interchangeably in the context of this module as the ecosystem transitions to the Auth.js branding.
    • Nuxt-specific features: While the core logic is powered by NextAuth, NuxtAuth adds Nuxt-specific layers like application-side composables (useAuth), authentication middleware, and plugins that manage the lifecycle (e.g., refreshing authentication on tab re-focus).
  4. Understand the meaning of 'provider' in NuxtAuth

    main

    The term provider in NuxtAuth can refer to two distinct concepts depending on the context:

    1. Module-level Provider: The authentication strategy selected in your Nuxt configuration via the provider.type key. Supported types include local, refresh, or authjs.
    2. OAuth Provider: The specific external service (e.g., Google, GitHub) used when the authjs module type is selected.
  5. Understand the difference between application-side and server-side code

    main

    In NuxtAuth, understanding where your code executes is critical for managing authentication state correctly:

    • application / application-side / universal-application: Refers to Nuxt code that is universally rendered. This code runs on both the server-side and the client-side (e.g., components, composables, and plugins). Because it executes twice, authentication logic or state access may behave differently depending on the environment.
    • server / server-side: Refers to code that runs exclusively on the server, such as files within the ~/server directory (API routes, server middleware).
  6. Access the JWT token on the application side

    main

    Since the JWT token is stored in a cookie accessible to the server, you cannot access it directly in client-side Vue components. To access JWT data in your .vue pages, you have two options:

    1. Create an API endpoint: Create a server-side route that uses getToken to return the token, then fetch that endpoint from your component.
    2. Inject data into the session: Modify the jwt callback within your NuxtAuthHandler configuration to include specific token data in the session object, making it available via the useAuth composable.
  7. Protect applications and endpoints

    main

    @sidebase/nuxt-auth provides multiple layers of protection:

    • Application-side protection: Use middleware to protect the full application globally or protect specific pages locally.
    • Server-side protection: Use server-side middleware and endpoint protection to secure your API routes and server logic.
  8. How NuxtAuth is architected

    main

    NuxtAuth is designed as a wrapper around existing, trusted open-source implementations rather than a ground-up rewrite. Specifically, it wraps NextAuth.js to leverage its mature ecosystem of authentication providers and security implementations.

    Key architectural decisions include:

    • NextAuth.js Integration: Utilizing the logic from the Next.js ecosystem to ensure stability and provider support.
    • Nuxt-native Composables: Translating NextAuth.js client logic into Nuxt 3+ patterns, such as the useAuth composable.
    • Lifecycle Management: The session lifecycle is triggered via a Nuxt plugin rather than the useAuth composable itself, allowing useAuth to operate as a synchronous operation for better developer experience.
  9. Understand how `baseURL` and endpoint paths are resolved

    main

    In @sidebase/nuxt-auth, the baseURL acts as a prefix for authentication requests. When defining endpoints in your provider configuration, the final URL is determined by the following logic:

    1. Prefixing: If an endpoint path is a relative path (e.g., /login), it is prepended with the baseURL.
    2. Full URLs: If an endpoint path is a fully specified URL (e.g., https://example.com/user), the baseURL is ignored for that specific call, and the provided URL is used directly.

    This allows you to mix local authentication routes with external identity provider endpoints.

    export default defineNuxtConfig({
      auth: {
        baseURL: 'https://example.com/api/auth',
    
        provider: {
          type: 'local',
          endpoints: {
            // The call would be made to `https://example.com/api/auth/login`
            signIn: { path: '/login', method: 'post' },
          }
        }
      }
    })
  10. Choose an authentication provider

    main

    The library supports two primary providers depending on your application type:

    • authjs: Designed for non-static applications. It brings the reliability of Auth.js / NextAuth.js to the Nuxt 3+ ecosystem with a native developer experience.
    • local: Designed for static pages that rely on an external backend using a credential flow. The Local Provider also supports refresh tokens.
  11. Protect specific pages with Local Middleware

    main

    If you are not using global middleware, you can protect individual pages using definePageMeta.

    There are two ways to do this:

    1. Automatic: Set auth: true. This automatically adds the sidebase-auth middleware to the end of your middleware array.
    2. Manual: Explicitly add 'sidebase-auth' to the middleware array. This allows you to control the exact execution order.

    Warning: Local middleware is only available if globalAppMiddleware is disabled. If global middleware is enabled, attempting to use local middleware will result in an error.

    <script lang="ts" setup>
    definePageMeta({
      auth: true // [!code focus]
    })
    </script>
    
    <template>
      I am now protected again!
    </template>
    <script lang="ts" setup>
    definePageMeta({
      middleware: 'sidebase-auth' // [!code focus]
    })
    </script>
    
    <template>
      I am now protected manually!
    </template>