优化结构
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"golang.org/x/sync/singleflight"
|
||||
@@ -14,6 +15,10 @@ import (
|
||||
|
||||
const claimsKey = "admin_claims"
|
||||
|
||||
// tokenAuthTimeout bounds a shared token authentication flight. It replaces the
|
||||
// leader request's own deadline, which followers must not inherit.
|
||||
const tokenAuthTimeout = 10 * time.Second
|
||||
|
||||
var refreshTokens singleflight.Group
|
||||
|
||||
type TokenAuthenticator interface {
|
||||
@@ -36,7 +41,7 @@ func AuthenticateWebSocket(c *gin.Context, auth TokenAuthenticator) bool {
|
||||
}
|
||||
|
||||
func authenticate(c *gin.Context, auth TokenAuthenticator, allowQueryToken bool) bool {
|
||||
token := requestToken(c, allowQueryToken)
|
||||
token := RequestToken(c, allowQueryToken)
|
||||
if token == "" {
|
||||
NoAuth(c, "未登录或非法访问,请登录")
|
||||
return false
|
||||
@@ -45,8 +50,15 @@ func authenticate(c *gin.Context, auth TokenAuthenticator, allowQueryToken bool)
|
||||
NoAuth(c, "认证服务不可用")
|
||||
return false
|
||||
}
|
||||
// Followers of a singleflight flight must not inherit the leader's request
|
||||
// context: if the leader's client disconnects mid-flight, its cancellation
|
||||
// would surface as an auth failure for every follower and force-log-out
|
||||
// unrelated sessions. Detach cancellation and bound the shared call with an
|
||||
// explicit timeout instead.
|
||||
value, err, _ := refreshTokens.Do(token, func() (any, error) {
|
||||
return auth.AuthenticateToken(c.Request.Context(), token)
|
||||
ctx, cancel := context.WithTimeout(context.WithoutCancel(c.Request.Context()), tokenAuthTimeout)
|
||||
defer cancel()
|
||||
return auth.AuthenticateToken(ctx, token)
|
||||
})
|
||||
if err != nil {
|
||||
SetTokenCookie(c, "", -1)
|
||||
@@ -93,10 +105,6 @@ func RequestToken(c *gin.Context, allowQueryToken bool) string {
|
||||
return token
|
||||
}
|
||||
|
||||
func requestToken(c *gin.Context, allowQueryToken bool) string {
|
||||
return RequestToken(c, allowQueryToken)
|
||||
}
|
||||
|
||||
func tokenErrorMessage(err error) string {
|
||||
message := "无法处理此token"
|
||||
switch {
|
||||
|
||||
Reference in New Issue
Block a user