欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

nestjs實現(xiàn)圖形校驗和單點登錄的示例代碼

 更新時間:2023年05月12日 16:21:04   作者:Yoge  
本文主要介紹了nestjs實現(xiàn)圖形校驗和單點登錄的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

實現(xiàn)圖形校驗和單點登錄

效果圖

login.gif

前置條件

學(xué)習(xí)一下 nest

安裝

新建項目

 npm i -g @nestjs/cli
 nest new project-name
 npm run start:dev //啟動服務(wù)

目錄結(jié)構(gòu)

1683793619743.jpg

controllers

負(fù)責(zé)處理傳入的請求并將響應(yīng)返回給客戶端。(定義路由等)

import { Controller, Get } from '@nestjs/common';
@Controller()
export class AppController {
  constructor() {}
  @Get()
  getHello(): string {
    return 'hello world';
  }
}

controllers 常用裝飾器

常用裝飾器

@Controller(path)@Get(path)@Post(path)@Request(), @Req()@Response(), @Res()@Session()@Param(key?: string)@Body(key?: string)@Query(key?: string)@Headers(name?: string)
定義 root 路徑定義 get 請求和路徑定義 post 請求和路徑請求體(req)響應(yīng)體(res)session獲取 req.params 參數(shù)獲取 req.body 參數(shù)獲取 req.query 參數(shù)獲取 req.headers 參數(shù)

Module

@Global()
@Module({
  providers: [MyService],
  exports: [MyService],
})
export class AppModule {}
  • providers 屬性用來聲明模塊所提供的依賴注入 (DI) 提供者,它們將在整個模塊中共享。
  • exports 屬性用于導(dǎo)出模塊中的提供者以供其他模塊使用。
  • global 標(biāo)識符用于創(chuàng)建一個全局模塊。在任何地方都可以使用 @Inject() 裝飾器來注入其提供者。
  • imports 選項用于引入其他模塊中提供的依賴關(guān)系。

service

import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
  getHello(): string {
    return 'Hello World!';
  }
}

業(yè)務(wù)邏輯具體實現(xiàn)

如何生成圖形驗證碼

需要用到 svg-captcha 這個庫

npm i svg-captcha

nest 命令行創(chuàng)建一個 captcha 模塊nest g res captchanest 命令行:

image.png

import { Controller, Get, Response, Session } from '@nestjs/common';
import * as svgCaptcha from 'svg-captcha';
@Controller('captcha')
export class CaptchaController {
  @Get()
  async getCaptcha(@Response() res, @Session() session) {
    const captcha = svgCaptcha.create({
      size: 4,
      noise: 2,
    });
    session.captcha = captcha.text;
    res.type('svg');
    res.send(captcha.data);
  }
}

通過 session 將當(dāng)前會話的 captcha 存起來此時能通過:http://localhost:3000/captcha查看到效果圖

image.png

如何使用 session

npm i express-session
npm i -D @types/express-session

并且再 main.ts 中引入

import * as session from 'express-session';
// somewhere in your initialization file
app.use(
  session({
    secret: 'my-secret',
    resave: false,
    saveUninitialized: false,
  }),
);

接入 mongose

在本機(jī)下載 mogodb mogodb 官網(wǎng)下載

安裝 mongoose

npm install --save mongoose

在 app.modele 中引入

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
  imports: [MongooseModule.forRoot('mongodb://127.0.0.1:27017/nest')],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

創(chuàng)建 schemas

import { Document } from 'mongoose';
import * as mongoose from 'mongoose';
export interface User {
  account: string;
  password: string;
}
export interface UserDoc extends User, Document {}
export const UserSchema = new mongoose.Schema({
  password: { type: String, required: true },
  account: {
    type: String,
    required: true,
    unique: true,
  },
});
export const UserModel = mongoose.model<UserDoc>('User', UserSchema);

創(chuàng)建 auth 模塊

nest g res auth

實現(xiàn)注冊和登錄方法controller

import {
  Controller,
  Get,
  Body,
  Post,
  UseInterceptors,
  Req,
  Request,
  Res,
} from '@nestjs/common';
import { AuthService } from './auth.service';
import { CreateUserDto } from './dto/index';
import { ApiCreatedResponse } from '@nestjs/swagger';
import { CaptchaMiddleware } from 'src/middleware/captcha-middleware/captcha-middleware.middleware';
@Controller('auth')
export class AuthController {
  constructor(private readonly authService: AuthService) {}
  @ApiCreatedResponse({
    description: 'The record has been successfully created.',
    type: CreateUserDto,
  })
  @Post('register')
  async created(@Body() data: CreateUserDto) {
    const user = await this.authService.created(data);
    return user;
  }
  @UseInterceptors(CaptchaMiddleware)
  @Post('login')
  async login(
    @Body() data: CreateUserDto,
    @Req() request: Request,
    @Res() res,
  ) {
    const user = await this.authService.login(data, request);
    res.sendResponse(user);
  }
}

引入uuid 生成隨機(jī)數(shù)和userId做鍵值對映射,為單點登錄打下基礎(chǔ)。

引入jwt 生成token進(jìn)行校驗。

import { Injectable, UnauthorizedException } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import mongoose, { Model } from 'mongoose';
import { InjectModel } from '@nestjs/mongoose';
import { UserDoc } from '../schemas/user.schema';
import { loginMapDoc } from '../schemas/login.mapping';
import { CreateUserDto } from './dto/index';
import { v4 as uuid } from 'uuid';
@Injectable()
export class AuthService {
  constructor(
    private jwtService: JwtService,
    @InjectModel('user') private readonly userModel: Model<UserDoc>,
    @InjectModel('loginmapModel')
    private readonly loginmapModel: Model<loginMapDoc>,
  ) {}
  async created(data: CreateUserDto) {
    const user = await new this.userModel(data);
    return user.save();
  }
  async login(data: any, req) {
    const { account, password, code } = data;
    if (code.toLocaleLowerCase() !== req.session?.captcha.toLocaleLowerCase()) {
      return {
        code: 400,
        message: '驗證碼錯誤',
      };
    }
    const user = await this.userModel.findOne({
      account,
      password,
    });
    if (!user) {
      throw new UnauthorizedException();
    }
    const loginId = uuid();
    const payload = {
      userId: user.id,
      username: user.account,
      loginId: loginId,
    };
    const token = this.jwtService.sign(payload);
    const foundCollection = await mongoose.connection.collections[
      'loginmapModel'
    ];
    if (!foundCollection) {
      // 如果該 collection 不存在,則創(chuàng)建它
      await new this.loginmapModel();
      console.log('新建成功');
    }
    await this.loginmapModel.findOneAndUpdate(
      { userId: user.id },
      { userId: user.id, loginId },
      { upsert: true, new: true, runValidators: true },
    );
    return { token, loginId };
  }
  async viladate(data: any) {
    const { userId, loginId } = data;
    const map = await this.loginmapModel.findOne({ userId, loginId });
    return loginId == map.loginId;
  }
}

最后創(chuàng)建一個guard,對用戶是否登錄進(jìn)行攔截判斷

nest g gu middleware/auth
import {
  CanActivate,
  ExecutionContext,
  Injectable,
  Request,
  UnauthorizedException,
} from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { JwtService } from '@nestjs/jwt';
import { jwtConstants } from '@/auth/constants';
import { AuthService } from '@/auth/auth.service';
@Injectable()
export class AuthGuardGuard implements CanActivate {
  constructor(
    private jwtService: JwtService,
    private reflector: Reflector,
    private authService: AuthService,
  ) {}
  async canActivate(context: ExecutionContext): Promise<boolean> {
    const skipAuth = this.reflector.get<boolean>(
      'skipAuth',
      context.getHandler(),
    ); // 返回 Boolean 值或 undefined,即是否跳過校驗
    if (skipAuth) {
      return true;
    }
    const request: Request = context.switchToHttp().getRequest();
    const token = this.extractTokenFromHeader(request);
    if (!token) {
      throw new UnauthorizedException();
    }
    try {
      const payload = await this.jwtService.verifyAsync(token, {
        secret: jwtConstants.secret,
      });
      const isRemoteLogin = await this.authService.viladate(payload);
      console.log(isRemoteLogin, 'payload', payload);
      if (!isRemoteLogin) {
        throw new UnauthorizedException('異地登錄');
      }
      // ?? We're assigning the payload to the request object here
      // so that we can access it in our route handlers
      request['user'] = payload;
    } catch {
      throw new UnauthorizedException();
    }
    return true;
  }
  private extractTokenFromHeader(request: any): string | undefined {
    const [type, token] = request.headers.authorization?.split(' ') ?? [];
    return type === 'Bearer' ? token : undefined;
  }
}

到此這篇關(guān)于nestjs實現(xiàn)圖形校驗和單點登錄的示例代碼的文章就介紹到這了,更多相關(guān)nestjs 圖形校驗和單點登錄內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論