@nest-auth/auth
TypeScript icon, indicating that this package has built-in type declarations

0.3.0 • Public • Published

Nest Auth

nestjs module to handle session based authentication

Installation

$ npm install --save @nest-auth/auth

Or

$ yarn add @nest-auth/auth

Install peer dependencies

$ npm install --save @nest-auth/cipher @nestjs/passport passport @nestjs/typeorm typeorm body-parser class-transformer class-validator cookie-parser csurf hbs passport-local

Or

$ yarn add @nest-auth/cipher @nestjs/passport passport @nestjs/typeorm typeorm body-parser class-transformer class-validator cookie-parser csurf hbs passport-local

Optionally install the password strength estimator

$ npm install --save zxcvbn

Or

$ yarn add zxcvbn

Create the User and Social Login entities

import { Entity } from 'typeorm';
import { AuthUser, AuthSocialLogin } from '@nest-auth/auth';

@Entity()
export class UserEntity extends AuthUser() {
  @OneToMany(() => SocialLoginEntity, sl => sl.user, {
    eager: true,
  })
  socialLogins: SocialLoginEntity[];
}

@Entity()
export class SocialLoginEntity extends AuthSocialLogin() {
  @ManyToOne(() => UserEntity, u => u.socialLogins, {
    onDelete: 'CASCADE',
  })
  user: Promise<UserEntity>;
}

Create the Auth controller

import { Controller } from '@nestjs/common';
import { AuthController } from '@nest-auth/auth';

@AuthController('auth')
export class AppAuthController {}

Import it in a module

import { Module } from '@nestjs/common';
import { AuthModule } from '@nest-auth/auth';

@Module({
  imports: [
    //...
    AuthModule.forRoot({
      // Required options
      userEntity: UserEntity,
      socialLoginEntity: SocialLoginEntity,
      // Optional
      connection: 'default', // Typeorm connection name
      minPasswordScore: undefined, // if passed, ensures that the password meets the passed minimun score, uses the zxcvbn package
      registerDto: RegisterDto, // Dto that should extend RegisterDto, useful to add more data to the user during registration
    }),
    
    // Or with Async configuration
    AuthModule.forRootAsync({
      import: [ConfigModule],
      inject: [ConfigService],
      useFactory: config => config.get('auth'),
    }),
    //...
  ],
  controllers: [
    // Do not forget to register the Auth controller
    AppAuthController,
  ],
})
export class AppModule {}

Add auth middleware to the underlying Express adapter

// main.ts

import { NestApplication } from '@nestjs/core';
import { addAuthMiddlewares } from '@nest-auth/auth';

const app = await NestApplication.create(AppModule, {
  //...
});

//...

addAuthMiddlewares(app, {
  sessionSecret: 'supersecret',
  clientDir: './client',
  sessionStore: store, // Compatible express session store,
  session: session, // compatible express session (`express-session`),
});

//...

await app.listen(3000);

Create authentication views

Create a views directory inside the clientDir directory (ex. client/views)

Create the required views:

  • login.html
  • register.html

For now, the only supported view engine is handlebars with .html extension


This configuration created thw following url:

  • GET /login: show login form login.html view. It receives as data
    • csrfToken: required to be set as _csrf form field
    • action: url to call as POST to handle authentication
  • POST /login: handle the login request. Login the user and redirect to the homepage or the value of the redirect_uri query param
  • GET /register: show the registration form register.html view. It receives as data
    • csrfToken: required to be set as _csrf form field
    • action: url to call as POST to handle authentication
  • POST /register: handle the registration request. Register the user, logs in him and redirect to the homepage or the redirect_uri query param
  • POST /logout: logs out the user and redirect to the homepage or the redirect_uri query param

Protect the routes

Guard a route with the AuthenticatedGuard to ensure the user is authenticated. It returns a standard 403 json error

To ensure the user is redirected to the Login page, add the Filter ForbiddenExceptionFilter to the same route

Get the user

To get the user from session, use the @CurrentUser param decorator

Example

import { Controller, Get, Render, UseFilters, UseGuards } from '@nestjs/common';
import { AuthenticatedGuard, ForbiddenExceptionFilter, CurrentUser } from '@nest-auth/auth';
import { User } from '../entities';

@Controller()
export class PrivateController {
  @UseFilters(ForbiddenExceptionFilter)
  @UseGuards(AuthenticatedGuard)
  @Render('private')
  @Get('/private')
  private(
    @CurrentUser() user: User,
  ) {
    return {
      message: 'You are authenticated',
      user,
    }
  }

  @UseGuards(AuthenticatedGuard)
  @Get('/api/private')
  apiPrivate(
    @CurrentUser() user: User,
  ) {
    return {
      message: 'You are authenticated',
      user,
    }
  }
}

Readme

Keywords

none

Package Sidebar

Install

npm i @nest-auth/auth

Weekly Downloads

0

Version

0.3.0

License

MIT

Unpacked Size

96.2 kB

Total Files

103

Last publish

Collaborators

  • davide-gheri