---

title: OpenAPI安全规范与自动扫描最佳实践

keywords:

  • OpenAPI
  • Swagger
  • 安全方案
  • securitySchemes
  • scopes
  • Lint
  • 自动扫描
  • 参数约束
  • 必填校验
  • 报告

description: 统一OpenAPI安全规范并实现自动扫描,校验securitySchemes与路径授权、参数类型与范围、必填字段与响应一致性,附扫描器与报告聚合示例。

categories:

  • 文章资讯
  • 技术教程

---

一、模型与输入

type SecurityScheme = { type: 'http' | 'apiKey' | 'oauth2'; name?: string; scheme?: string }
type Operation = { security?: string[]; parameters?: { name: string; in: 'query' | 'header' | 'path' | 'cookie'; required?: boolean; schema?: { type: 'string' | 'number' | 'boolean'; min?: number; max?: number } }[] }
type PathItem = { [method: string]: Operation }
type OpenApiDoc = { securitySchemes: Record<string, SecurityScheme>; paths: Record<string, PathItem> }

二、校验规则

function hasSecurity(doc: OpenApiDoc, op: Operation): boolean {
  const list = op.security || []
  return list.every(k => !!doc.securitySchemes[k])
}

function validParam(p: Operation['parameters'][number]): boolean {
  const s = p.schema
  if (!s) return false
  if (s.type === 'string') return true
  if (s.type === 'number') return typeof s.min === 'number' && typeof s.max === 'number' && s.min <= s.max
  if (s.type === 'boolean') return true
  return false
}

function requiredOk(p: Operation['parameters'][number]): boolean {
  if (p.in === 'path') return p.required === true
  return true
}

三、扫描器与报告

type Issue = { path: string; method: string; code: string; detail: string }

function scan(doc: OpenApiDoc): Issue[] {
  const out: Issue[] = []
  for (const [path, item] of Object.entries(doc.paths)) {
    for (const [method, op] of Object.entries(item)) {
      if (!hasSecurity(doc, op)) out.push({ path, method, code: 'missing_security', detail: 'operation without security' })
      for (const p of op.parameters || []) {
        if (!requiredOk(p)) out.push({ path, method, code: 'path_param_required', detail: p.name })
        if (!validParam(p)) out.push({ path, method, code: 'param_invalid', detail: p.name })
      }
    }
  }
  return out
}

四、聚合与验收

class Aggregator { counts = new Map<string, number>(); inc(k: string) { const n = (this.counts.get(k) || 0) + 1; this.counts.set(k, n) } top() { return Array.from(this.counts.entries()).sort((a,b)=>b[1]-a[1]) } }

function aggregate(issues: Issue[]): Aggregator { const agg = new Aggregator(); for (const i of issues) agg.inc(i.code); return agg }
  • 所有操作声明安全方案并存在;路径参数标记required=true;数字参数具备最小最大范围。
  • 报告聚合包含问题码与计数;输出按路径与方法可定位;可作为CI检查的一部分。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部