updete
Some checks failed
Build Multi-Platform Binaries / build-frontend (push) Successful in 30s
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Successful in 1m4s
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Successful in 45s
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Successful in 1m29s
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Successful in 45s
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Successful in 1m27s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Successful in 50s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Successful in 1m42s
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Has been cancelled
Some checks failed
Build Multi-Platform Binaries / build-frontend (push) Successful in 30s
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Successful in 1m4s
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Successful in 45s
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Successful in 1m29s
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Successful in 45s
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Successful in 1m27s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Successful in 50s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Successful in 1m42s
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Has been cancelled
This commit is contained in:
100
internal/server/router/handler/auth.go
Normal file
100
internal/server/router/handler/auth.go
Normal file
@@ -0,0 +1,100 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"crypto/subtle"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
// removed router import
|
||||
"github.com/gotunnel/internal/server/router/dto"
|
||||
"github.com/gotunnel/pkg/auth"
|
||||
"github.com/gotunnel/pkg/security"
|
||||
)
|
||||
|
||||
// AuthHandler 认证处理器
|
||||
type AuthHandler struct {
|
||||
username string
|
||||
password string
|
||||
jwtAuth *auth.JWTAuth
|
||||
}
|
||||
|
||||
// NewAuthHandler 创建认证处理器
|
||||
func NewAuthHandler(username, password string, jwtAuth *auth.JWTAuth) *AuthHandler {
|
||||
return &AuthHandler{
|
||||
username: username,
|
||||
password: password,
|
||||
jwtAuth: jwtAuth,
|
||||
}
|
||||
}
|
||||
|
||||
// Login 用户登录
|
||||
// @Summary 用户登录
|
||||
// @Description 使用用户名密码登录,返回 JWT token
|
||||
// @Tags 认证
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body dto.LoginRequest true "登录信息"
|
||||
// @Success 200 {object} Response{data=dto.LoginResponse}
|
||||
// @Failure 400 {object} Response
|
||||
// @Failure 401 {object} Response
|
||||
// @Router /api/auth/login [post]
|
||||
func (h *AuthHandler) Login(c *gin.Context) {
|
||||
var req dto.LoginRequest
|
||||
if !BindJSON(c, &req) {
|
||||
return
|
||||
}
|
||||
|
||||
// 验证用户名密码 (使用常量时间比较防止时序攻击)
|
||||
userMatch := subtle.ConstantTimeCompare([]byte(req.Username), []byte(h.username)) == 1
|
||||
passMatch := subtle.ConstantTimeCompare([]byte(req.Password), []byte(h.password)) == 1
|
||||
|
||||
if !userMatch || !passMatch {
|
||||
security.LogWebLogin(c.ClientIP(), req.Username, false)
|
||||
Unauthorized(c, "invalid credentials")
|
||||
return
|
||||
}
|
||||
|
||||
// 生成 token
|
||||
token, err := h.jwtAuth.GenerateToken(req.Username)
|
||||
if err != nil {
|
||||
InternalError(c, "failed to generate token")
|
||||
return
|
||||
}
|
||||
|
||||
security.LogWebLogin(c.ClientIP(), req.Username, true)
|
||||
Success(c, dto.LoginResponse{Token: token})
|
||||
}
|
||||
|
||||
// Check 检查 token 是否有效
|
||||
// @Summary 检查 Token
|
||||
// @Description 验证 JWT token 是否有效
|
||||
// @Tags 认证
|
||||
// @Produce json
|
||||
// @Security Bearer
|
||||
// @Success 200 {object} Response{data=dto.TokenCheckResponse}
|
||||
// @Failure 401 {object} Response
|
||||
// @Router /api/auth/check [get]
|
||||
func (h *AuthHandler) Check(c *gin.Context) {
|
||||
authHeader := c.GetHeader("Authorization")
|
||||
if authHeader == "" {
|
||||
Unauthorized(c, "missing authorization header")
|
||||
return
|
||||
}
|
||||
|
||||
const prefix = "Bearer "
|
||||
if len(authHeader) < len(prefix) || authHeader[:len(prefix)] != prefix {
|
||||
Unauthorized(c, "invalid authorization format")
|
||||
return
|
||||
}
|
||||
tokenStr := authHeader[len(prefix):]
|
||||
|
||||
claims, err := h.jwtAuth.ValidateToken(tokenStr)
|
||||
if err != nil {
|
||||
Unauthorized(c, "invalid token")
|
||||
return
|
||||
}
|
||||
|
||||
Success(c, dto.TokenCheckResponse{
|
||||
Valid: true,
|
||||
Username: claims.Username,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user