You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Suave应用中拦截未授权IP请求并返回403停止路由

解决Suave中未授权IP直接返回403的问题

嘿,完全懂你的需求——你要的不是“跳过当前路由继续找下一个”,而是直接终止请求处理,立刻返回403状态码对吧?Suave里确实有简洁的方式实现这个,不需要复杂的分支组合器,自定义一个中间件风格的WebPart就能搞定。

步骤1:定义授权IP列表和IP获取逻辑

首先,先把你的授权IP存成一个集合(方便快速查找),再写个函数从请求上下文里拿到客户端IP:

open Suave
open Suave.Http
open Suave.Http.Successful
open Suave.Http.Writers
open System.Collections.Generic

// 你的授权IP列表
let allowedIps = Set ["127.0.0.1"; "192.168.1.100"]

// 获取客户端IP(如果部署在反向代理后,记得从X-Forwarded-For头取)
let getClientIp (ctx: HttpContext) =
    match ctx.request.headers with
    | Some headers when headers.ContainsKey "X-Forwarded-For" ->
        headers.["X-Forwarded-For"].Split(',') |> Array.head |> fun s -> s.Trim()
    | _ ->
        ctx.request.clientIpAddress.ToString()

步骤2:编写IP授权组合器

接下来写一个核心的WebPart组合器,它会先检查IP是否在授权列表里:

  • 如果在,就把请求传递给后续的路由处理
  • 如果不在,直接返回403响应,终止处理流程
let ipAuthorization (next: WebPart) : WebPart =
    fun ctx ->
        let clientIp = getClientIp ctx
        if allowedIps.Contains clientIp then
            // IP合法,继续处理后续路由
            next ctx
        else
            // IP不合法,直接返回403
            OK "Forbidden" 
            |> withStatusCode 403 
            |> fun response -> response ctx

步骤3:把组合器应用到你的路由上

最后,把这个授权组合器放在整个路由树的最前面,这样所有请求都会先经过IP检查:

let app =
    ipAuthorization >=> choose [
        path "/api/secure" >=> OK "This is secure content"
        path "/" >=> OK "Welcome to home page"
        // 其他路由...
    ]

为什么之前的过滤器不行?

你之前用的过滤器应该是filter组合器吧?它的逻辑是“条件满足就处理,不满足就跳过当前WebPart,继续找下一个路由”——这就是为什么它只是中断了当前路由搜索,却没有返回403。而我们上面写的组合器是主动返回了一个响应,直接终止了整个请求处理流程,完全符合你的需求。

如果想更简洁,也可以用choose直接把IP检查作为第一个分支:

let checkUnauthorizedIp =
    fun ctx ->
        let clientIp = getClientIp ctx
        if not (allowedIps.Contains clientIp) then
            Some (OK "Forbidden" |> withStatusCode 403)
        else
            None

let app =
    choose [
        checkUnauthorizedIp
        path "/api/secure" >=> OK "Secure content"
        path "/" >=> OK "Home"
    ]

这种方式下,choose会先执行checkUnauthorizedIp,如果返回Some response就直接返回,否则继续处理后面的路由。

内容的提问来源于stack exchange,提问作者team-rf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:53:41