NodeJS
Node.js 如何克服 I/O 操作阻塞的问题
由于 node.js 有一个事件循环,可用于以异步方式处理所有 I/O 操作,而不会阻塞 main 函数。
- 如果需要进行一些网络调用,它将被安排在事件循环中,而不是主线程(单线程)中。
- 如果有多个这样的 I/O 调用,每个调用都会相应地排队分别执行(除了主线程)。 因此,即使我们有单线程 JS,I/O 操作也是以非阻塞方式处理的。
单线程:Node.js 是作为异步处理的实验显式创建的,即在单个线程上进行异步处理,而不是通过不同框架进行缩放的现有基于线程的实现。
Node.js 中有多少种 API 函数 ?
有两种类型的 API 函数:
- 异步、非阻塞函数:主要是 I/O 操作,可以从主循环中分叉出来。
- 同步的、阻塞的函数 :主要是影响在主循环中运行的进程的操作。
Node.js 中的 fork 是什么
- 通常,fork 用于生成子进程。
- 在 node 中,它用于创建一个新的 v8 引擎实例来运行多个 worker 来执行代码。
鉴权
- HTTP Basic Authentication (HTTP 基本认证)
- session-cookie
- Token 验证(包括 JWT,SSO)
- OAuth(开放授权)
我们普通网站常用的认证就是 session-cookie 的方式,用户向服务端发生请求,服务端会创建 session 并保存相关身份信息,并向客户端下发一个 sessionId,大家如果用心的话,会发现跟 JAVA 交互的时候,浏览器会有一个 JSESSION_ID,跟 PHP 交互的时候,会有一个 PHPSESSION_ID;后面的每次请求,客户端都会自动带上这个 cookie 跟服务端通信。
实际上大家要明白每一种方式的作用;SSO 主要用来做单点登录;OAuth 主要用来做第三方网站授权;JWT 就是一种便于扩展的跨域认证解决方案,通常会考察这个。
token 登录模式
Token 登录模式是一种在 Web 应用中进行身份验证和授权的常见方式。它基于令牌(Token)的概念,通过在客户端和服务器之间传递令牌来验证用户的身份和授权访问。
以下是 Token 登录模式的一般工作流程:
- 用户提供凭据:用户在登录页面上提供用户名和密码等凭据。
- 身份验证:服务器接收到用户提供的凭据后,进行身份验证。通常,服务器会检查用户名和密码是否匹配,并验证用户的身份。
- 生成令牌:如果身份验证成功,服务器会生成一个令牌(Token)。令牌是一个加密的字符串,其中包含有关用户身份和权限的信息。
- 令牌返回给客户端:服务器将生成的令牌发送回客户端作为登录凭据的一部分。通常,令牌会被存储在客户端的 Cookie 或本地存储中。
- 请求授权:客户端在后续的请求中将令牌包含在请求头、查询参数或 Cookie 中,并发送给服务器。
- 令牌验证:服务器接收到请求后,会验证令牌的有效性和完整性。服务器可以解密令牌并检查其中的信息,例如用户 ID、角色、权限等。
- 授权访问:如果令牌验证成功,服务器会授权用户访问请求的资源或执行请求的操作。服务器可以使用令牌中的信息来确定用户的权限级别和可访问的资源。
- 令牌过期和刷新:令牌通常具有过期时间。当令牌过期时,客户端可以使用刷新令牌(Refresh Token)来获取新的令牌,而无需重新进行身份验证。
Token 登录模式的主要优势包括:
- 无状态:服务器不需要在后端存储用户的会话信息,因为所有必要的信息都包含在令牌中。这使得服务器可以更轻松地进行水平扩展和负载均衡。
- 跨域支持:令牌可以在跨域请求中使用,因为令牌可以在请求头、查询参数或 Cookie 中传递。
- 安全性:令牌可以使用加密算法进行签名和验证,确保令牌的完整性和安全性。此外,令牌还可以通过设置短期过期时间和使用刷新令牌来增加安全性。
- 可扩展性:Token 登录模式可以与其他身份验证和授权机制结合使用,例如多因素身份验证、单点登录(SSO)等。
总的来说,Token 登录模式通过使用令牌来验证用户身份和授权访问,提供了一种安全、可扩展和无状态的身份验证机制。它已经成为现代 Web 应用中常见的身份验证方式之一。
什么是 NestJS?它有什么优点和特点?
NestJS 是一个用于构建高效、可扩展的服务器端应用程序的框架。它基于 TypeScript,并且使用了面向对象的编程(OOP)和函数式编程(FP)的概念,同时结合了 Express.js 的灵活性和 Angular 的模块化思想。以下是 NestJS 的一些优点和特点:
- 基于 TypeScript:NestJS 使用 TypeScript 作为主要开发语言,这使得代码更具可读性、可维护性和可扩展性。TypeScript 提供了静态类型检查和最新的 ECMAScript 特性支持,使开发过程更加高效和安全。
- 模块化架构:NestJS 借鉴了 Angular 的模块化思想,通过模块的概念将应用程序划分为一组功能相关的模块。这种模块化的架构使得应用程序的组织和维护更加简单和可扩展。
- 强大的依赖注入(DI):NestJS 提供了一个强大的依赖注入容器,可以方便地管理和组织应用程序的各个组件和服务。依赖注入使得代码解耦、可测试性更强,并且有助于实现可扩展的架构。
- 内置的 HTTP 框架支持:NestJS 内置了对 Express.js 的支持,并提供了一组装饰器和工具,简化了处理 HTTP 请求和响应的过程。这使得开发者可以使用熟悉的 Express.js API,并且能够轻松地集成其他中间件和插件。
- 强大的路由系统:NestJS 提供了一个灵活且易于使用的路由系统,可以通过装饰器和装饰器链式调用的方式定义路由和请求处理程序。这种声明式的路由定义方式使得代码更加清晰和可读,并且提供了更好的可维护性。
- 可插拔的中间件支持:NestJS 支持使用中间件来处理请求和响应,这使得开发者可以在请求处理过程中添加各种功能,例如身份验证、日志记录、错误处理等。NestJS 的中间件系统支持全局中间件和局部中间件,提供了灵活的配置选项。
- 良好的生态系统:NestJS 拥有庞大的生态系统,提供了许多官方和第三方的模块、插件和工具,可以方便地集成和使用其他流行的库和框架,例如 TypeORM、GraphQL、WebSocket 等。
总的来说,NestJS 是一个功能强大、可扩展的服务器端应用程序框架,它结合了 TypeScript 的优势、模块化架构、依赖注入、内置的 HTTP 框架支持和强大的路由系统等特点。这些特点使得开发者可以更轻松地构建可维护、可测试和高效的应用程序。
Nestjs 的核心设计思想和原理
NestJS 的核心设计思想是使用现代化的面向对象编程(OOP)和函数式编程(FP)的概念来构建可扩展、模块化和可测试的应用程序。以下是一些与 NestJS 相关的核心设计思想和原理:
- 模块化架构:NestJS 使用模块化的架构来组织应用程序。每个功能相关的组件(例如控制器、服务、中间件等)都被组织在一个模块中。模块之间可以相互依赖和引用,从而构建出一个完整的应用程序。这种模块化的设计使得应用程序的组织和维护更加简单和可扩展。
- 依赖注入(DI):NestJS 提供了一个强大的依赖注入容器,用于管理应用程序中的组件和服务。依赖注入使得代码解耦、可测试性更强,并且有助于实现可扩展的架构。通过将依赖关系的创建和解析委托给 DI 容器,NestJS 可以自动处理组件之间的依赖关系,并在需要时创建和注入相应的实例。
- 路由系统:NestJS 提供了一个灵活且易于使用的路由系统,用于处理 HTTP 请求。开发者可以使用装饰器和装饰器链式调用的方式来定义路由和请求处理程序。这种声明式的路由定义方式使得代码更加清晰和可读,并且提供了更好的可维护性。NestJS 的路由系统支持常见的 HTTP 方法(GET、POST、PUT、DELETE 等),并且可以处理各种路由参数和查询参数。
- 中间件支持:NestJS 支持使用中间件来处理请求和响应。中间件可以在请求处理过程中添加各种功能,例如身份验证、日志记录、错误处理等。NestJS 的中间件系统支持全局中间件和局部中间件,可以灵活配置和使用。
- 异步编程:NestJS 鼓励使用异步编程来提高应用程序的性能和可伸缩性。它提供了一些异步编程的机制,例如异步服务、异步控制器方法、异步中间件等。这些机制可以与 JavaScript 的异步特性(例如 Promise、async/await)结合使用,使开发者能够编写高效的异步代码。
- 强大的生态系统:NestJS 拥有庞大的生态系统,提供了许多官方和第三方的模块、插件和工具,可以方便地集成和使用其他流行的库和框架,例如 TypeORM、GraphQL、WebSocket 等。这些模块和插件可以通过简单的配置和集成,扩展 NestJS 的功能和能力。
通过这些核心设计思想和原理,NestJS 提供了一个强大且灵活的框架,使开发者能够构建可扩展、模块化和可测试的应用程序。它结合了现代化的编程概念和丰富的生态系统,为构建复杂的服务器端应用程序提供了便利和效率。
Express 的核心设计思想和原理
Express 的核心设计思想和原理:
- 中间件架构:Express 使用中间件架构来处理请求和响应。中间件是一个函数,可以访问请求对象(req)、响应对象(res)和下一个中间件函数(next)。每个请求都会经过一系列的中间件函数,每个中间件函数可以对请求和响应进行处理或者将控制权传递给下一个中间件函数。这种中间件架构使得开发者可以按照需要添加、删除或者修改中间件,从而实现灵活的请求处理逻辑。
- 路由系统:Express 提供了一个简单而灵活的路由系统,用于定义和处理不同的路由。开发者可以使用路由定义来匹配请求的 URL 和 HTTP 方法,并指定相应的处理函数。这使得开发者可以根据不同的 URL 和方法,定义不同的请求处理逻辑。
- 请求和响应对象:Express 提供了方便的请求对象(req)和响应对象(res),使开发者能够访问和操作请求和响应的各个方面,例如请求头、请求体、响应头、响应体等。这些对象提供了许多有用的方法和属性,使开发者能够更轻松地处理和操作请求和响应。