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 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部
2.058313s