1.4.24-edge • Published 2 years ago

@bg-dev/nuxt-auth v1.4.24-edge

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

Nuxt Auth

npm version npm downloads License Nuxt

A fairly complete solution to handle authentication for your Nuxt 3 project

Features

  • ✔️ Email/password authentication
  • ✔️ Email verification & password reset flows
  • ✔️ Oauth login (Google, Github ...)
  • ✔️ Route middleware protection
  • ✔️ Database agnostic (Prisma based)
  • ✔️ Auth operations via useAuth composable
  • ✔️ Auto refresh of access token via useAuthFetch composable
  • ✔️ Add dynamic custom claims to access token
  • ✔️ Customizable email templates
  • ✔️ User session management via useAuthSession composable
  • ✔️ Admin management via useAuthAdmin composable
  • ✔️ Edge deployment on Vercel, Netlify, Cloudflare ...

Installation

Add @bg-dev/nuxt-auth dependency to your project

# Using npm
npm install --save-dev @bg-dev/nuxt-auth

# Using yarn
yarn add --dev @bg-dev/nuxt-auth

Setup

Add @bg-dev/nuxt-auth to the modules section of nuxt.config.ts and set auth config option

export default defineNuxtConfig({
  modules: ["@bg-dev/nuxt-auth"],

  auth: {
    accessToken: {
      jwtSecret: "", // JWT secret (required)
      maxAge: 30 * 60, // 30 Minutes
      customClaims: {}, // Dynamic custom claims
    },
    refreshToken: {
      cookieName: "auth_refresh_token",
      jwtSecret: "", // JWT secret (required)
      maxAge: 7 * 24 * 60 * 60, // 7 days
    },
    oauth: { // Oauth providers's config (optional)
      "<provider>": {
        clientId: "",
        clientSecret: "",
        scopes: "",
        authorizeUrl: "",
        tokenUrl: "",
        userUrl: ""
      }
    },
    smtp: { // SMTP server's config (optional)
        host: "",
        port: "",
        user: "",
        pass: "",
        from: ""
    },
    emailTemplates: { // Html email templates (optional)
        passwordReset: "",
        emailVerify: ""
    },
    prisma: {}, // Prisma client options (optional)
    registration: {
        enable: true,
        requireEmailVerification: true,
        passwordValidationRegex: "",
        defaultRole: "user"
    },
    baseUrl: "", // Nuxt app base url, used for external redirects
    enableGlobalAuthMiddleware: false, // Enable auth middleware on every page
    webhookKey: "", // Webhook key used in the Webhook-Key header
    redirect: {
      login: "", // Path to redirect to when login is required
      logout: "", // Path to redirect to after logout
      home: "", //  Path to redirect to after successful login
      callback: "", // Path to redirect to after login with provider
      passwordReset: "", // Path to redirect to for password reset
      emailVerify: "", // Path to redirect to after email verification
    },
    admin: {
      enable: true, // Enable admin API
    }
  },.
});

Setup Prisma if not already set

npx prisma init

Copy the default schema definition to your prisma/schema.prisma file & optionally add your custom fields

SQL

model User {
  id            Int            @id @default(autoincrement())
  name          String
  email         String         @unique
  picture       String
  role          Role           @default(user)
  provider      Provider       @default(default)
  password      String?
  verified      Boolean        @default(false)
  suspended     Boolean        @default(false)
  refreshTokens RefreshToken[]
  createdAt     DateTime       @default(now())
  updatedAt     DateTime       @updatedAt
}

model RefreshToken {
  id        Int      @id @default(autoincrement())
  uid       String
  userId    Int
  user      User     @relation(fields: [userId], references: [id])
  userAgent String?
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  @@index([userId])
}

enum Role {
  user
  admin
}

enum Provider {
  default
  google
}

Mongo DB

model User {
  id            String         @id @default(auto()) @map("_id") @db.ObjectId
  name          String
  email         String         @unique
  picture       String
  role          Role           @default(user)
  provider      Provider       @default(default)
  password      String?
  verified      Boolean        @default(false)
  suspended     Boolean        @default(false)
  refreshTokens RefreshToken[]
  createdAt     DateTime       @default(now())
  updatedAt     DateTime       @updatedAt
}

model RefreshToken {
  id        String   @id @default(auto()) @map("_id") @db.ObjectId
  uid       String
  userId    String   @db.ObjectId
  user      User     @relation(fields: [userId], references: [id])
  userAgent String?
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  @@index([userId])
}

enum Role {
  user
  admin
}

enum Provider {
  default
  google
}

Run a migration to reflect schema changes to your database & generate prisma client

SQL

npx prisma migrate dev

Mongo DB

npx prisma db push

That's it! You can now use @bg-dev/nuxt-auth in your Nuxt app ✨

Usage

Route protection

For protecting page routes, 2 possible approachs can be used

  • Globally enable and locally disable
enableGlobalAuthMiddleware: true;
definePageMeta({ auth: false });
  • Locally enable
definePageMeta({ middleware: "auth" }); // Redirects to login path when not loggedIn
definePageMeta({ middleware: "guest" }); // Redirects to home path when loggedIn

Custom claims

For adding custom claims to the access token's payload, set the customClaims accessToken's option in the nuxt.config.ts. For User related dynamic values, use the mustache syntax.

customClaims: {
  "https://hasura.io/jwt/claims": {
    "x-hasura-allowed-roles": ["user", "admin"],
    "x-hasura-default-role": "{{role}}",
    "x-hasura-user-id": "{{id}}",
  },
},

Email templates

For adding your own email templates, set the emailTemplates options in nuxt.config.ts. Exposed variables are User, link for redirection and validityInMinutes (equals to accessToken maxAge).

emailTemplates: {
  passwordReset: `
    <html lang="en">
      <head>
        <style>
          body {
           background-color: #f1f5f9;
           color: #0f172a;
           font-family: "Arial";
           padding: 8px;
         }
        </style>
      </head>

     <body>
       <h2>Hello {{name}},</h2>
       <p>To reset your password, please follow this link</p>
       <a href="{{link}}">Reset your password</a>
       <p>Valid for {{validityInMinutes}} minutes</p>
     </body>
    </html>
    `,
}

Authorization

For adding a server side auth protection, create server/middleware/auth.ts and copy the handler below. On protected server routes check event.context.auth property.

import { getAccessTokenFromHeader, verifyAccessToken } from "#auth";

export default defineEventHandler((event) => {
  try {
    const accessToken = getAccessTokenFromHeader(event);
    if (accessToken) {
      const payload = verifyAccessToken(accessToken);
      event.context.auth = payload;
    }
  } catch (error) {}
});

Graphql authorization

For data fetching with Graphql, you can use nuxt-apollo module.

export default defineNuxtPlugin({
  enforce: "pre",
  hooks: {
    "apollo:http-auth": async (args) => {
      const accessToken = await getAccessToken();
      args.token = accessToken;
    },
  },
});

Hooks

The module provides auth:loggedIn hook for implementing custom login on user login and logout events

export default defineNuxtPlugin({
  enforce: "pre", // Should be registered before built-in plugin
  hooks: {
    "auth:loggedIn": async (loggedIn) => {},
  },
});

Notes

  • The module implements a JWT based authentication. The Session abstract used in the module refers to a Refresh token stored in DB

  • An admin is a user with role equals admin.

  • On production, include prisma generate step to the build command.

  • For security reasons, it's recommended to add rate limiting and CORS policy.

  • The redirect URI for oauth providers should be

{baseUrl}/api/auth/login/{provider}/callback
  • The sessions are subject to expiration in case the user does not refresh his login. To flush this useless data, the module exposes the following REST API
curl -X DELETE -H "Webhook-Key: {webhookKey}" {baseUrl}/api/auth/session/revoke/expired

Development

# Install dependencies
npm install

# Generate type stubs
npm run dev:prepare

# Develop with the playground
npm run dev

# Build the playground
npm run dev:build

# Run ESLint
npm run lint

# Run Vitest
npm run test
npm run test:watch

# Release new version
npm run release

Contributing

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contribution you make is greatly appreciated.

License

MIT License

3.0.3

11 months ago

3.0.2

1 year ago

3.0.0-edge.5

1 year ago

3.0.0-beta.1

2 years ago

3.0.0-beta.3

2 years ago

3.0.0-beta.2

2 years ago

3.0.0-beta.5

2 years ago

3.0.0-beta.4

2 years ago

3.0.1-rc

2 years ago

3.0.0-edge.1

2 years ago

3.0.0-edge.2

2 years ago

3.0.1

1 year ago

3.0.0

2 years ago

3.0.0-beta

2 years ago

3.0.0-edge.3

2 years ago

3.0.0-edge.4

2 years ago

3.0.2-rc

2 years ago

3.0.3-rc

2 years ago

3.0.0-beta.19

2 years ago

3.0.0-beta.10

2 years ago

3.0.0-beta.11

2 years ago

3.0.0-beta.12

2 years ago

3.0.0-beta.13

2 years ago

3.0.0-beta.14

2 years ago

3.0.0-beta.15

2 years ago

3.0.0-beta.16

2 years ago

3.0.0-beta.17

2 years ago

3.0.4-rc

2 years ago

3.0.0-beta.18

2 years ago

2.5.6-edge

2 years ago

2.5.5-edge

2 years ago

2.6.0

2 years ago

2.5.4-edge

2 years ago

2.5.3-edge

2 years ago

2.5.2-edge

2 years ago

2.5.1

2 years ago

2.5.0-edge

2 years ago

2.5.0

2 years ago

2.5.1-edge

2 years ago

2.4.13-edge

2 years ago

2.4.8

2 years ago

2.4.12-edge

2 years ago

2.4.11-edge

2 years ago

2.4.7

2 years ago

2.4.10-edge

2 years ago

2.4.9-edge

2 years ago

2.4.6

2 years ago

2.4.5

2 years ago

2.4.4

2 years ago

2.4.8-edge

2 years ago

2.4.3

2 years ago

2.4.7-edge

2 years ago

2.4.2

2 years ago

2.4.6-edge

2 years ago

2.3.8

2 years ago

2.4.5-edge

2 years ago

2.4.4-edge

2 years ago

2.3.7

2 years ago

2.3.6

2 years ago

2.3.5

2 years ago

2.4.3-edge

2 years ago

2.4.0-edge

2 years ago

2.4.2-edge

2 years ago

2.4.1-edge

2 years ago

2.3.2

2 years ago

2.3.4

2 years ago

2.3.3

2 years ago

2.3.2-edge

2 years ago

2.3.1-edge

2 years ago

2.2.11-edge

2 years ago

2.2.5-edge

2 years ago

2.2.12-edge

2 years ago

2.3.0

2 years ago

2.3.1

2 years ago

2.2.9-edge

2 years ago

2.2.6-edge

2 years ago

2.2.8-edge

2 years ago

2.2.7-edge

2 years ago

2.1.0-edge

2 years ago

2.2.1

2 years ago

2.2.0

2 years ago

2.2.10-edge

2 years ago

2.2.4-edge

2 years ago

2.2.0-edge

2 years ago

2.2.3-edge

2 years ago

2.2.1-edge

2 years ago

2.1.1-edge

2 years ago

2.2.2-edge

2 years ago

2.1.2-edge

2 years ago

1.4.2-edge

2 years ago

1.4.5-edge

2 years ago

2.0.10-edge

2 years ago

1.4.37-edge

2 years ago

1.4.18-edge

2 years ago

2.0.7-edge

2 years ago

2.0.2

2 years ago

1.4.31-edge

2 years ago

1.4.34-edge

2 years ago

1.4.8-edge

2 years ago

2.0.13-edge

2 years ago

2.0.16-edge

2 years ago

2.0.1

2 years ago

2.0.5-rc

2 years ago

1.4.27-edge

2 years ago

1.4.43-edge

2 years ago

1.4.12-edge

2 years ago

1.4.44-edge

2 years ago

1.4.21-edge

2 years ago

1.4.11-edge

2 years ago

1.4.22-edge

2 years ago

1.4.25-edge

2 years ago

1.4.41-edge

2 years ago

1.4.36-edge

2 years ago

2.1.1-rc

2 years ago

1.4.39-edge

2 years ago

2.0.3-rc

2 years ago

2.0.6-edge

2 years ago

2.0.9-edge

2 years ago

1.4.40-edge

2 years ago

2.0.8-edge

2 years ago

1.4.10-edge

2 years ago

1.4.9-edge

2 years ago

1.4.38-edge

2 years ago

1.4.24-edge

2 years ago

1.4.29-edge

2 years ago

1.4.4

2 years ago

1.4.26-edge

2 years ago

1.4.3

2 years ago

1.4.2

2 years ago

1.4.1

3 years ago

1.4.23-edge

2 years ago

1.4.20-edge

2 years ago

2.0.1-rc

2 years ago

1.4.45-edge

2 years ago

1.4.42-edge

2 years ago

1.4.19-edge

2 years ago

1.4.35-edge

2 years ago

2.0.12-edge

2 years ago

2.0.5-edge

2 years ago

2.1.0-rc

2 years ago

2.0.11-edge

2 years ago

1.4.7-edge

2 years ago

1.4.6-edge

2 years ago

2.0.4-rc

2 years ago

1.4.13-edge

2 years ago

2.0.17-edge

2 years ago

1.4.30-edge

2 years ago

2.0.14-edge

2 years ago

1.4.33-edge

2 years ago

1.4.28-edge

2 years ago

1.4.17-edge

2 years ago

2.1.0

2 years ago

2.0.15-edge

2 years ago

1.4.16-edge

2 years ago

1.4.32-edge

2 years ago

1.4.4-edge

2 years ago

1.4.15-edge

2 years ago

1.4.3-edge

2 years ago

2.0.2-rc

2 years ago

1.4.0

3 years ago

1.3.5

3 years ago

1.3.4

3 years ago

1.3.3

3 years ago

0.1.6

3 years ago

1.3.2

3 years ago

1.3.1

3 years ago

1.3.0

3 years ago

0.1.4

3 years ago

0.1.5

3 years ago

1.3.0-rc.8

3 years ago

1.3.0-rc.9

3 years ago

0.1.2

3 years ago

0.1.1

3 years ago

1.3.0-rc.2

3 years ago

1.3.0-rc.3

3 years ago

1.3.0-rc.1

3 years ago

1.3.0-rc.6

3 years ago

0.1.3

3 years ago

1.3.0-rc.7

3 years ago

1.3.0-rc.4

3 years ago

1.3.0-rc.5

3 years ago

1.2.1-rc.7

3 years ago

1.2.1-rc.6

3 years ago

1.2.1-rc.5

3 years ago

1.2.1-rc.4

3 years ago

1.2.1-rc.3

3 years ago

1.3.0-rc.10

3 years ago

1.2.1-rc.2

3 years ago

1.2.1-rc.1

3 years ago

1.2.0

3 years ago

1.1.1

3 years ago

1.1.0

3 years ago

1.1.0-beta.29

3 years ago

1.1.0-beta.28

3 years ago

1.1.0-beta.27

3 years ago

1.1.0-beta.26

3 years ago

1.1.0-beta.25

3 years ago

1.1.0-beta.24

3 years ago

1.1.0-beta.23

3 years ago

1.1.0-beta.22

3 years ago

1.1.0-beta.21

3 years ago

1.1.0-beta.20

3 years ago

1.1.0-beta.19

3 years ago

1.1.0-beta.18

3 years ago

1.1.0-beta.17

3 years ago

1.1.0-beta.16

3 years ago

1.1.0-beta.15

3 years ago

1.1.0-beta.14

3 years ago

1.1.0-beta.13

3 years ago

1.1.0-beta.12

3 years ago

1.1.0-beta.11

3 years ago

1.1.0-beta.10

3 years ago

1.1.0-beta.9

3 years ago

1.1.0-beta.8

3 years ago

1.1.0-beta.7

3 years ago

1.1.0-beta.6

3 years ago

1.1.0-beta.5

3 years ago

1.1.0-beta.4

3 years ago

1.1.0-beta.3

3 years ago

1.1.0-beta.2

3 years ago

1.1.0-beta.1

3 years ago

1.0.1

3 years ago

1.0.1-alpha.12

3 years ago

1.0.1-alpha.11

3 years ago

1.0.1-alpha.10

3 years ago

1.0.1-alpha.6

3 years ago

1.0.1-alpha.5

3 years ago

1.0.1-alpha.4

3 years ago

1.0.1-alpha.3

3 years ago

1.0.1-alpha.2

3 years ago

1.0.1-alpha.1

3 years ago

1.0.0

3 years ago