Nestjs自定义注解实现接口权限控制详解

下面我将详细讲解一下 “Nestjs自定义注解实现接口权限控制”的完整攻略。

1. 背景

在开发过程中,接口权限控制是一个非常重要的问题,通常实现的方式有基于角色、基于路由等等,但是这些方式灵活性较差,不够便捷。本攻略将详细介绍如何使用 Nestjs 自定义注解实现接口权限控制。

2. 环境准备

在开始之前,需要确保已经安装 nestjsreflect-metadata,安装方式如下:

npm i --save @nestjs/core reflect-metadata

3. 自定义注解实现接口权限控制

在 Nestjs 中,使用自定义注解实现接口权限控制的方式如下:

3.1. 编写权限功能代码

在权限功能代码中,我们需要实现如下逻辑:

  1. 定义注解:使用 Reflect Metadata 定义一个自定义注解,在注解中定义该接口需要的权限。
  2. 获取用户信息:获取当前用户的信息,通常是从用户的 token 中获取。这里我们假设我们从请求头中获取了用户的 token。
  3. 判断用户是否拥有权限:根据用户信息和权限注解,判断用户是否拥有权限。

代码如下:

import { createParamDecorator, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { AuthFailedException } from './exceptions/auth-failed.exception';

const reflector = new Reflector();

interface User {
  id: number;
  name: string;
  roles: string[];
}

export const CurrentUser = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) => {
    const req = ctx.switchToHttp().getRequest();
    const token = req.headers['authorization']?.split(' ')[1];
    try {
      const user = parseToken(token);
      return user;
    } catch (error) {
      throw new AuthFailedException('Token 验证失败');
    }
  },
);

function parseToken(token: string): User {
  // 这里写具体的 token 解析逻辑,此处省略
  return {
    id: 1,
    name: 'foo',
    roles: ['admin'],
  };
}

export function Auth(role: string) {
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;
    descriptor.value = function (...args: any[]) {
      const user = args[0];
      const roles = user.roles;
      if (!roles.includes(role)) {
        throw new AuthFailedException(`无权操作:需要角色 ${role}`);
      }

      return originalMethod.apply(this, args);
    };
    return descriptor;
  };
}

3.2. 在控制器中使用权限注解

在控制器中使用权限注解,只需要在需要权限控制的接口上添加 @Auth 注解即可,如下所示:

@Controller()
export class AppController {
  @Post('admin')
  @Auth('admin')
  createToken(@Body() body: CreateTokenDto) {
    return this.userService.createToken(body);
  }
}

在上面的例子中,createToken 方法需要具备 admin 权限。

4. 示例说明

下面给出两个示例,以便更好地理解如何使用自定义注解实现接口权限控制:

4.1. 示例 1

我们在开发一个权限管理的系统中,需要对用户进行管理,其中管理员用户能够对普通用户进行增、删、改、查的操作,而普通用户只有对自己进行增、删、改、查的权限。此时,我们可以使用自定义注解对 user 接口进行权限控制。

@Controller()
export class UserController {
  @Post('user')
  @Auth('normal')
  createUser(@Body() body: CreateUserDto) {
    // 创建用户
  }

  @Put('user/:id')
  @Auth('normal')
  updateUser(@Param('id') id: string, @Body() body: UpdateUserDto, @CurrentUser() user: User) {
    if (user.id !== id) {
      throw new AuthFailedException(`无权操作`);
    }
    // 更新用户
  }

  @Delete('user/:id')
  @Auth('normal')
  deleteUser(@Param('id') id: string, @CurrentUser() user: User) {
    if (user.id !== id) {
      throw new AuthFailedException(`无权操作`);
    }
    // 删除用户
  }

  @Get('users')
  @Auth('admin')
  getUsers() {
    // 获取所有用户
  }
}

在上面的例子中,createUser/updateUser/deleteUser 方法需要具备 normal 权限,getUsers 方法需要具备 admin 权限。

4.2. 示例 2

在开发一个博客系统中,需要对博客进行管理,其中管理员用户能够对自己的博客进行所有操作,而普通用户只能编辑自己的博客。此时,我们可以使用自定义注解对 blog 接口进行权限控制。

@Controller()
export class BlogController {
  @Post('blog')
  @Auth('normal')
  createBlog(@Body() body: CreateBlogDto, @CurrentUser() user: User) {
    // 创建博客
  }

  @Put('blog/:id')
  @Auth('normal')
  updateBlog(@Param('id') id: string, @Body() body: UpdateBlogDto, @CurrentUser() user: User) {
    const blog = await this.blogService.findOne(id);
    if (user.id !== blog.authorId) {
      throw new AuthFailedException(`无权操作`);
    }
    // 更新博客
  }

  @Delete('blog/:id')
  @Auth('normal')
  deleteBlog(@Param('id') id: string, @CurrentUser() user: User) {
    const blog = await this.blogService.findOne(id);
    if (user.id !== blog.authorId) {
      throw new AuthFailedException(`无权操作`);
    }
    // 删除博客
  }

  @Get('blogs')
  @Auth('admin')
  getBlogs() {
    // 获取所有博客
  }
}

在上面的例子中,createBlog/updateBlog/deleteBlog 方法需要具备 normal 权限,getBlogs 方法需要具备 admin 权限。

5. 总结

本攻略介绍了如何使用自定义注解实现接口权限控制的方式,在应用程序中使用自定义注解,可以提高代码的可读性,可维护性和可重用性,加速开发流程。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Nestjs自定义注解实现接口权限控制详解 - Python技术站

(0)
上一篇 2023年6月8日
下一篇 2023年6月8日

相关文章

  • Node.js如何响应Ajax的POST请求并且保存为JSON文件详解

    首先,我们需要创建一个Node.js服务器,以响应Ajax的POST请求。具体步骤如下: 创建Node.js服务器 在终端中运行 mkdir my-project 创建一个新的项目文件夹,并进入该文件夹 cd my-project。 运行 npm init 命令来创建项目的 package.json 文件。 运行 npm install express 安装…

    node js 2023年6月8日
    00
  • node.js调用C++开发的模块实例

    下面我将为您详细讲解如何在 Node.js 中调用 C++ 开发的模块实例。 1. 安装node-gyp node-gyp 是 Node.js 的一个包装器,可以用于编译和构建包含 C++ 代码的 Node.js 模块。因此,在使用 C++ 编写的模块前,需要先安装 node-gyp。可使用以下命令进行安装: npm install -g node-gyp …

    node js 2023年6月8日
    00
  • nodejs初始化init的示例代码

    当我们开始用Node.js编写一个新的项目时,我们需要在项目的根目录中初始化一个Node.js应用程序。Node.js应用程序初始化是使用npm命令进行的,它可以生成我们的项目所需的文件和文件夹,以及内置依赖项和配置文件。 下面是一个Node.js初始化示例: 打开命令行工具,进入项目根目录,执行以下命令: npm init 这将启动一个交互式环境,提示你输…

    node js 2023年6月8日
    00
  • node.js-path模块你了解多少

    下面是详细讲解“node.js-path模块”的攻略: 什么是path模块 在Node.js中,path模块提供了处理文件路径的工具,它可以轻松地处理Linux、Windows和OS X等操作系统的路径问题。Path通常是一个类UNIX风格的路径名,但是也支持Windows风格的路径名。Path模块提供了各种实用的功能来解析和组合路径。 Path模块的常用方…

    node js 2023年6月8日
    00
  • node.js中的buffer.Buffer.isBuffer方法使用说明

    下面来详细讲解“node.js中的buffer.Buffer.isBuffer方法使用说明”的完整攻略。 什么是Buffer Buffer是Node.js中的一个全局构造函数,它提供了对二进制数据的操作。Buffer的实例类似于整数数组,但Buffer的大小是固定的,它无法对其大小进行更改。 Buffer.isBuffer方法 Buffer.isBuffer…

    node js 2023年6月8日
    00
  • ESLint和Jest中使用esm示例详解

    ESLint和Jest中使用esm示例详解 简介 ESLint是一个开源的JavaScript代码检查工具,它的目标是保证代码的一致性和避免错误。ESLint支持插件,我们可以使用它来编写自定义规则,以便强制执行代码的有效性和可读性。 Jest是一个流行的JavaScript测试框架,可用于测试React、Vue等前端框架以及Node.js应用程序等等,其功…

    node js 2023年6月8日
    00
  • 利用types增强vscode中js代码提示功能详解

    利用types增强VS Code中JS代码提示功能,可以使得在代码编写过程中有更好的提示和自动补全,让代码更加高效、准确的完成。 1. 安装@types模块 首先需要安装项目相关的依赖@types模块,例如: npm install @types/react @types/react-dom –save-dev 该命令将会安装React和React-DOM…

    node js 2023年6月8日
    00
  • Nodejs中的this详解

    什么是this 在JavaScript中,this是一个很常用的关键字,用于指代函数当前的执行环境。在Nodejs中,this可以用于访问当前对象的属性或方法,或者用来调用其他函数。 this的使用 在创建对象的时候,this被用来指代该对象。例如,我们创建了一个Person对象,其中包含了name和age属性,方法如下: function Person(n…

    node js 2023年6月8日
    00
合作推广
合作推广
分享本页
返回顶部