WebSocket 安全实践:从认证到加密

在前三篇文章中,我们深入探讨了 WebSocket 的基础原理、服务端开发和客户端实现。今天,让我们把重点放在安全性上,看看如何构建一个安全可靠的 WebSocket 应用。我曾在一个金融项目中,通过实施多层安全机制,成功防御了多次恶意攻击尝试。

安全挑战

WebSocket 应用面临的主要安全挑战包括:

  1. 身份认证
  2. 数据加密
  3. 跨站点 WebSocket 劫持(CSWSH)
  4. 拒绝服务攻击(DoS)
  5. 中间人攻击

让我们逐一解决这些问题。

身份认证

实现安全的身份认证机制:

// auth-handler.js
class AuthHandler {
  constructor(options = {}) {
    this.options = {
      tokenSecret: process.env.TOKEN_SECRET,
      tokenExpiration: '24h',
      refreshTokenExpiration: '7d',
      ...options
    }

    this.blacklist = new Set()
  }

  // 生成访问令牌
  generateAccessToken(user) {
    return jwt.sign(
      {
        id: user.id,
        role: user.role,
        type: 'access'
      },
      this.options.tokenSecret,
      {
        expiresIn: this.options.tokenExpiration
      }
    )
  }

  // 生成刷新令牌
  generateRefreshToken(user) {
    return jwt.sign(
      {
        id: user.id,
        type: 'refresh'
      },
      this.options.tokenSecret,
      {
        expiresIn: this.options.refreshTokenExpiration
      }
    )
  }

  // 验证令牌
  verifyToken(token) {
    try {
      // 检查黑名单
      if (this.blacklist.has(token)) {
        throw new Error('Token has been revoked')
      }

      const decoded = jwt.verify(token, this.options.tokenSecret)

      // 验证令牌类型
      if (decoded.type !== 'access') {
        throw new Error('Invalid token type')
      }

      return decoded
    } catch (error) {
      throw new Error('Invalid token')
    }
  }

  // 刷新令牌
  async refreshToken(refreshToken) {
    try {
      const decoded = jwt.verify(refreshToken, this.options.tokenSecret)

      // 验证令牌类型
      if (decoded.type !== 'refresh') {
        throw new Error('Invalid token type')
      }

      // 获取用户信息
      const user = await this.getUserById(decoded.id)
      if (!user) {
        throw new Error('User not found')
      }

      // 生成新的访问令牌
      return this.generateAccessToken(user)
    } catch (error) {
      throw new Error('Invalid refresh token')
    }
  }

  // 吊销令牌
  revokeToken(token) {
    this.blacklist.add(token)
  }

  // 清理过期的黑名单令牌
  cleanupBlacklist() {
    this.blacklist.forEach(token => {
      try {
        jwt.verify(token, this.options.tokenSecret)
      } catch (error) {
        // 令牌已过期,从黑名单中移除
        this.blacklist.delete(token)
      }
    })
  }

  // WebSocket 握手认证
  handleHandshake(request) {
    return new Promise((resolve, reject) => {
      const token = this.extractToken(request)

      if (!token) {
        reject(new Error('No token provided'))
        return
      }

      try {
        const decoded = this.verifyToken(token)
        resolve(decoded)
      } catch (error) {
        reject(error)
      }
    })
  }

  // 从请求中提取令牌
  extractToken(request) {
    const auth = request
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值