---

title: GraphQL输入验证与错误处理安全指南

keywords:

  • GraphQL
  • 输入验证
  • 自定义Scalar
  • 错误处理
  • Rate Limit
  • 白名单

description: 通过自定义Scalar与输入类型校验、统一错误处理与速率限制,构建稳健的GraphQL输入安全与可预期错误模型。

categories:

  • 文章资讯
  • 技术教程

---

GraphQL输入验证与错误处理安全指南

概述

GraphQL灵活输入容易触发类型绕过与高负载。通过输入校验与错误约束可有效降低风险。

自定义Scalar与校验

import { GraphQLScalarType, Kind } from 'graphql'

export const EmailScalar = new GraphQLScalarType({
  name: 'Email',
  serialize(value: unknown) {
    const s = String(value)
    if (!/^\S+@\S+\.\S+$/.test(s)) throw new TypeError('invalid_email')
    return s
  },
  parseValue(value: unknown) {
    const s = String(value)
    if (!/^\S+@\S+\.\S+$/.test(s)) throw new TypeError('invalid_email')
    return s
  },
  parseLiteral(ast) {
    if (ast.kind !== Kind.STRING) throw new TypeError('invalid_email')
    if (!/^\S+@\S+\.\S+$/.test(ast.value)) throw new TypeError('invalid_email')
    return ast.value
  }
})

输入类型白名单

input CreateUserInput {
  email: Email!
  name: String!
  role: String @allowed(values: ["user", "admin"]) 
}

统一错误模型

type ApiError = { code: string; message: string }

function safeError(err: unknown): ApiError {
  const code = err instanceof Error ? err.message : 'unknown_error'
  const map: Record<string, string> = {
    invalid_email: '邮箱格式不正确',
    forbidden: '权限不足',
    rate_limited: '请求过于频繁'
  }
  return { code, message: map[code] || '请求处理失败' }
}

速率限制

class SimpleLimiter {
  windowMs: number
  max: number
  hits = new Map<string, number[]>()
  constructor(windowMs: number, max: number) { this.windowMs = windowMs; this.max = max }
  allow(key: string): boolean {
    const now = Date.now()
    const arr = (this.hits.get(key) || []).filter(t => now - t < this.windowMs)
    if (arr.length >= this.max) return false
    arr.push(now)
    this.hits.set(key, arr)
    return true
  }
}

运维要点

  • 为关键输入定义自定义Scalar并在Schema中强制使用
  • 将错误统一映射为安全可读的代码与消息
  • 对高风险变更接口实施速率限制与审计

以上方法可在保持GraphQL灵活性的同时,实现稳健的输入安全与错误模型。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部