TypeScript中的授权与身份验证:完整指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

TypeScript中的授权与身份验证:从理论到实践



在现代Web开发中,应用程序安全是基石。TypeScript作为JavaScript的严格类型化超集,为构建可靠的身份验证(验证用户身份)和授权(验证访问权限)系统提供了强大的工具。在本文中,我们将探讨关键概念、流行库,并用TypeScript编写一个可运行的示例。



基本概念:身份验证 vs 授权



这两个术语经常被混淆。让我们明确区分:

  • 身份验证(Authentication) — 验证您是谁的过程。例如,通过用户名和密码登录,或通过第三方服务(Google、GitHub)登录。
  • 授权(Authorization) — 验证您可以做什么的过程。例如,访问管理面板或删除帖子的权限。


在TypeScript中,这些过程通过中间件(中间处理程序)实现,在执行请求之前检查令牌或会话。



TypeScript的流行库



在TypeScript项目中实现授权与身份验证时,最常用的库包括:

  • jsonwebtoken — 用于处理JWT(JSON Web令牌)。
  • bcrypt — 用于密码哈希。
  • passport(配合类型@types/passport)— 用于Express的灵活中间件。
  • express-session — 用于服务器端会话管理。
  • crypto — Node.js内置模块,用于哈希处理。


实践示例:TypeScript中的JWT身份验证



让我们创建一个简单的REST API,通过JWT进行身份验证。示例将基于Express + TypeScript。



步骤1. 安装依赖

npm install express jsonwebtoken bcrypt dotenvnpm install -D typescript @types/express @types/jsonwebtoken @types/bcrypt ts-node nodemon


步骤2. TypeScript配置(tsconfig.json)

{  "compilerOptions": {    "target": "ES2020",    "module": "commonjs",    "outDir": "./dist",    "rootDir": "./src",    "strict": true,    "esModuleInterop": true  }}


步骤3. 创建身份验证中间件

// src/middleware/auth.tsimport { Request, Response, NextFunction } from 'express';import jwt from 'jsonwebtoken';

interface UserPayload { id: string; email: string;}

// 扩展Request接口以存储用户数据declare global { namespace Express { interface Request { user?: UserPayload; } }}

export const authenticate = ( req: Request, res: Response, next: NextFunction): void => { const authHeader = req.headers.authorization;

if (!authHeader || !authHeader.startsWith('Bearer ')) { res.status(401).json({ message: '未提供令牌' }); return; }

const token = authHeader.split(' ')[1];

try { const decoded = jwt.verify( token, process.env.JWT_SECRET || 'default_secret' ) as UserPayload; req.user = decoded; next(); } catch (error) { res.status(401).json({ message: '无效令牌' }); }};


步骤4. 基于角色的授权中间件

// src/middleware/authorize.tsimport { Request, Response, NextFunction } from 'express';

export const authorize = (...allowedRoles: string[]) => { return (req: Request, res: Response, next: NextFunction): void => { // 假设角色在身份验证后存储在req.user中 const userRole = (req as any).user?.role || 'user';

if (!allowedRoles.includes(userRole)) { res.status(403).json({ message: '访问被拒绝' });

推荐