---
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灵活性的同时,实现稳健的输入安全与错误模型。

发表评论 取消回复