41 lines
1.3 KiB
Go
41 lines
1.3 KiB
Go
package middleware
|
||
|
||
import (
|
||
"net/http"
|
||
|
||
"fashionapi/internal/pkg/response"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
)
|
||
|
||
// SSGToken 是 SSG 内部端口的「防御纵深」鉴权中间件。
|
||
//
|
||
// 设计取舍:
|
||
// - token 为空字符串时直接放行(noop)。因为 SSG 端口本身只绑在 127.0.0.1(回环),
|
||
// 外部网络根本连不进来,本地开发/单机构建无需令牌也能保证安全。
|
||
// - token 非空时,请求必须携带 ?token=<secret> 或 X-SSG-Token: <secret> 头,
|
||
// 否则返回 401。用于「即便回环被意外暴露(如误绑 0.0.0.0)」时的最后一道闸。
|
||
//
|
||
// 注意:该中间件只装在 SSG 内部引擎上,对外公开引擎(8090)从不装载,
|
||
// 因此不会给公网接口引入任何额外逻辑。
|
||
func SSGToken(token string) gin.HandlerFunc {
|
||
// 未配置令牌:回环绑定已足够,直接放行。
|
||
if token == "" {
|
||
return func(c *gin.Context) { c.Next() }
|
||
}
|
||
|
||
return func(c *gin.Context) {
|
||
// 优先从查询参数取(astro build 的 node fetch 拼 URL 最方便),
|
||
// 其次从自定义请求头取(便于 curl / CI 手动调用)。
|
||
got := c.Query("token")
|
||
if got == "" {
|
||
got = c.GetHeader("X-SSG-Token")
|
||
}
|
||
if got != token {
|
||
response.AbortError(c, http.StatusUnauthorized, "invalid or missing ssg token")
|
||
return
|
||
}
|
||
c.Next()
|
||
}
|
||
}
|