TypeScript 安全认证:专业指南

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

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

开始课程

您的数据岌岌可危:为什么 TypeScript 中的认证绝非儿戏

\n\n

想象一下:您用 TypeScript 创建了一个很棒的应用程序。它运行流畅,类型严格,代码美观。但有一个小细节——认证。这时,好戏才刚刚开始。一个错误——用户数据就会像水从指缝间流走一样泄露。熟悉吗?

\n\n

在 2024 年,安全认证不仅仅是“加个登录功能”。它是一门完整的科学。而 TypeScript 是您最好的朋友。它不会让您意外传递错误的数据类型,会在您忘记验证令牌时提醒您,并在编译时拯救您于愚蠢的错误之中。

\n\n

在本文中,我们将探讨如何从零开始构建TypeScript 应用程序中的安全认证。没有废话——只有真实的示例、最佳实践和一点点黑色幽默(怎能少了它)。

\n\n

JWT:一见令牌就倾心

\n\n

JSON Web Token (JWT) 是现代 Web 应用程序中认证的事实标准。但是,正如本叔叔所说,“能力越大,责任越大”。JWT 既可以是一面盾牌,也可以是一颗定时炸弹。

\n\n

不应该怎么做:反面示例

\n\n

新手最常见的错误是将令牌存储在 localStorage 中并以明文形式传输。是的,这行得通。但这就像把家门钥匙放在门垫下——看似方便,但任何路人都可以进来。XSS 攻击——您所有的令牌都会落入攻击者手中。

\n\n

在 TypeScript 中正确处理 JWT

\n\n

让我们编写一个安全的令牌处理包装器。TypeScript 在这里将帮助我们避免混淆类型并忘记验证。

\n\n
import jwt from 'jsonwebtoken';\n\ninterface TokenPayload {\n  userId: string;\n  role: 'user' | 'admin';\n  iat?: number;\n  exp?: number;\n}\n\n// 使用清晰的类型定义生成令牌\nfunction generateAccessToken(payload: TokenPayload): string {\n  return jwt.sign(\n    { ...payload },\n    process.env.JWT_SECRET as string,\n    { expiresIn: '15m' }\n  );\n}\n\n// 验证并立即转换为我们的接口\nfunction verifyAccessToken(token: string): TokenPayload | null {\n  try {\n    return jwt.verify(\n      token, \n      process.env.JWT_SECRET as string\n    ) as TokenPayload;\n  } catch (error) {\n    console.error('令牌验证失败:', error);\n    return null;\n  }\n}
\n\n

请注意:我们始终检查 JWT_SECRET 是否存在且为字符串。TypeScript 强制我们这样做——运行时绝不允许出现 undefined!

\n\n

密码哈希:bcrypt 前来救援

\n\n

以明文形式存储密码是一种犯罪。即使您的数据库比 Fort Knox 还要安全,一次入侵——您就会作为又一次“密码泄露”登上新闻。密码哈希是您的救命稻草。

\n\n

为什么选择 bcrypt 而不是 MD5?

\n\n

MD5 已经过时。SHA-256 也不是选项。现代 GPU 每秒可以处理数十亿个哈希。Bcrypt 则是特意设计为缓慢的。它使用盐(随机数据)和可调整的成本因子。成本越高——计算哈希所需时间越长。而这正是好事!

\n\n

在 TypeScript 中的实现

\n\n
import bcrypt from 'bcrypt';\n\nconst SALT_ROUNDS = 12; // 2024 年的最佳值\n\nasync function hashPassword(password: string): Promise<string> {\n  const salt = await bcrypt.genSalt(SALT_ROUNDS);\n  return bcrypt.hash(password, salt);\n}\n\nasync function comparePassword(\n  password: string, \n  hash: string\n): Promise<boolean> {\n  return bcrypt.compare(password, hash);\n}\n\n// 用于注册的类型化函数\ninterface CreateUserInput {\n  email: string;\n  password: string;\n  name: string;\n}\n\nasync function createUser(input: CreateUserInput): Promise<Omit<User, 'passwordHash'>> {\n  const passwordHash = await hashPassword(input.password);\n  \n  // 保存到数据库(此处为您的代                

博客

书籍推荐