Skip to content

4sllan/nuxt-simple-auth

Repository files navigation

Auth Module Simple

Authentication support for Nuxt 3


nuxt-simple-auth


npm version GitHub License npm downloads Nuxt Static Badge

nuxt-simple-auth is an authentication module for Nuxt 3, designed as an open-source, robust, and * feature-rich* package. It enables cookie validation and CSRF protection, seamlessly integrating with Laravel Passport.
Additionally, it supports various cookie parameters for both login and two-factor authentication (2FA).
It also includes SSR authentication support, ensuring that the user remains authenticated on both the client and the server.

While the package is stable in terms of options and behavior, there are still improvements to be made, and some bugs may exist.

Start

npx nuxi@latest module add nuxt-simple-auth

Setup

Installation

Add nuxt-simple-auth to the modules section in nuxt.config.js.

Configuration

The configuration must be done in the nuxt.config.js file by adding the library to the modules section.

In the auth property, defining strategies is mandatory, while cookies and CSRF settings are **optional **.

For authentication, the endpoints.login property requires the use of Laravel Passport, which must expose the /oauth/token route.
Laravel Passport Documentation - Client Credentials Grant Tokens

This route must return a JSON response containing the following attributes:

  • access_token
  • refresh_token
  • expires_in

If you choose to use 2FA authentication, the package requires the configuration of endpoints.2fa, which mandates that Laravel exposes a specific route.
This route should return a JSON response with the following attributes:

  • access_token
  • expires_in

expires_in: Must be the number of seconds until the 2FA access token expires.

After 2FA validation, the token will be automatically added to the headers of requests as a Bearer Token, with the name "2fa".
This allows Laravel APIs to validate authentication on protected routes.

Example

export default defineNuxtConfig({
    modules: [
        'nuxt-simple-auth'
    ],

    auth: {
        csrf: '/csrf-token',
        cookie: {
            options: {
                httpOnly: true,
                secure: true,
                sameSite: 'Lax',
                priority: 'high',
            },
            prefix: '__Secure-auth.'
        },
        strategies: {
            local: {
                redirect: {
                    logout: "/auth",
                    login: "/auth"
                },
                user: {
                    property: "profile",
                },
                endpoints: {
                    login: {url: "/oauth/token", method: "post", alias: "auth token"},
                    user: {url: "/api/profile", method: "get"},
                    "2fa": {url: "/api/send-token-2fa", method: "post"},
                },
            }
        }
    },
});

Runtime Config

The runtimeConfig of Nuxt 3 must also be configured to include a secret object.
This object should contain the names of your strategies, and within each strategy, the following keys are **required **:

Example Configuration:

export default defineNuxtConfig({
    runtimeConfig: {
        secret: {
            local: {
                client_id: 'YOUR_CLIENT_ID',
                client_secret: 'YOUR_CLIENT_SECRET',
                grant_type: 'password',
            },
            client: {
                client_id: 'YOUR_CLIENT_ID',
                client_secret: 'YOUR_CLIENT_SECRET',
                grant_type: 'authorization_code',
            }
        }
    }
});

Strategies

The strategies configuration follows the structure below, starting with a name of your choice to set up the package.
The available options are listed, indicating which are required and which are optional.

Configuration

  • redirect: Defines the pages for redirection. (Required)

    • login: (Optional)
    • logout: (Required)
    • callback: (Optional)
    • home: (Optional)
  • endpoints: Defines the API routes configured in Laravel. (Required)

    • login: (Required)
      • url: (Required)
      • method: (Required)
      • alias: (Optional)
    • user: Contains user data. (Required)
      • url: (Required)
      • method: (Required)
    • "2fa": (Optional)
      • url: (Required)
      • method: (Required)
      • alias: (Optional)
    • logout: (Optional)
      • alias: (Optional)
  • user: Name of the object containing user data. (Optional)


 strategies: {
            local: {
                redirect: {
                    logout: "/auth",
                    login: "/auth"
                },
                user: {
                    property: "profile",
                },
                endpoints: {
                    login: {url: "/oauth/token", method: "post", alias: "auth token"},
                    user: {url: "/api/profile", method: "get"},
                    "2fa": {url: "/api/send-token-2fa", method: "post"},
                },
            },
            client:{
                redirect: {
                    logout: "/auth",
                    login: "/auth"
                },
                endpoints: {
                    login: {url: "/oauth/token", method: "post"},
                    user: {url: "/api/profile", method: "get"},
                    "2fa": {url: "/api/send-token-2fa", method: "post"},
                    logout: {alias: 'logout client'}
                },
            }
        }

2FA is optional, but if included in one of the "strategies," it must have a URL and method to enable the "_2fa" middleware. This middleware is not global and can be selectively used on Nuxt pages.

 definePageMeta({
      middleware: ['auth', '_2fa']
    });

Cookie

Option Description
prefix Default token prefix used in constructing a key for token storage.
options Additional cookie options, passed to cookie.
path Path where the cookie is visible. Default is /.
expires Specifies the lifetime of the cookie in number of days or a specific date. Default is session-only.
maxAge Specifies the number (in seconds) that will be the Max-Age value (preferably expired).
domain Domain (and by extension subdomains) where the cookie is visible. Default is the domain and all subdomains.
secure Defines whether the cookie requires a secure protocol (HTTPS). Default is false, should be set to true if possible.

Notes:

  • By default, the prefix on localhost is set to "auth."
  • __Secure- prefix: Cookies with names starting with __Secure- (dash is part of the prefix) must be set with the secure flag from a secure page (HTTPS).
  • __Host- prefix: Cookies with names starting with __Host- must be set with the secure flag, must originate from a secure page (HTTPS), must not have a domain specified (and therefore are not sent to subdomains), and the path must be /.
cookie: {
        options: {
            httpOnly: true,
                secure: true,
                sameSite: 'Lax',
                priority: 'high',
            //maxAge: 24 * 60 * 60 * 1000,
        },
        prefix: '__Secure-auth.',
    }

Middlewares

The nuxt-simple-auth package provides two middlewares: "auth" and "_2fa".
They are not global and can be applied selectively to Nuxt pages.

  • auth: Restricts access to protected pages, ensuring the user is authenticated via Laravel Passport, both on the client and server (SSR).
  • _2fa: Enhances authentication by verifying values stored in cookies and sessionStorage to validate * *two-factor authentication (2FA)**, also working on both the client and server (SSR).
 definePageMeta({
      middleware: ['auth', '_2fa']
    });

Methods

Método / Method Description
loginWith(strategyName, ...args) Sets the current strategy and attempts to log in. Returns a Promise.
logout(strategyName) Logs out, ensuring the destruction of cookies and state.
_2fa(strategyName, ...args) Attempts to validate the two-factor authentication (2FA) code. Returns a Promise.
refreshToken(strategyName)
$auth.headers.set(name, value) Sets an HTTP header manually.
$auth.headers.get(name) Retrieves the value of an HTTP header.

Usage Examples

loginWith

const {$auth} = useNuxtApp()

$auth.loginWith('local', data)
    .then(response => {
        // Logic after login
    })

logout

const {$auth} = useNuxtApp()

$auth.logout('local')

_2fa

$auth._2fa('local', data).then(response => {
    // Logic after 2FA validation
})

Headers and Requests

$auth.headers.set('name', 'value') // Sets a header  
$auth.headers.get('name') // Retrieves a header  

const {data, pending, error, refresh} = useFetch(url, {
    headers: $auth.headers,
})

⚖️ License

Released under MIT by @4slan.