first commit
This commit is contained in:
80
internal/middleware/auth.go
Normal file
80
internal/middleware/auth.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"licserver/internal/utils"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func JWTAuth(config *utils.JWTConfig) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
var token string
|
||||
|
||||
// 1. 首先从 cookie 中获取 token
|
||||
tokenCookie, err := c.Cookie("token")
|
||||
if err == nil {
|
||||
token = tokenCookie
|
||||
}
|
||||
|
||||
// 2. 如果 cookie 中没有,则从 header 中获取
|
||||
if token == "" {
|
||||
auth := c.GetHeader("Authorization")
|
||||
if auth != "" {
|
||||
parts := strings.SplitN(auth, " ", 2)
|
||||
if len(parts) == 2 && parts[0] == "Bearer" {
|
||||
token = parts[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 如果 query 参数中有 token,也可以使用
|
||||
if token == "" {
|
||||
token = c.Query("token")
|
||||
}
|
||||
|
||||
// 如果都没有找到 token
|
||||
if token == "" {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "未提供认证信息"})
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
// 验证 token
|
||||
claims, err := utils.ParseToken(token, config)
|
||||
if err != nil {
|
||||
// 如果 token 无效,清除 cookie
|
||||
// c.SetCookie("token", "", -1, "/", "", true, true)
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "无效的token"})
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
// 将用户信息存储到上下文
|
||||
c.Set("userID", claims.UserID)
|
||||
c.Set("username", claims.Username)
|
||||
c.Set("role", claims.Role)
|
||||
|
||||
// 如果是从 header 或 query 参数获取的 token,设置到 cookie 中
|
||||
if tokenCookie == "" {
|
||||
// 设置 cookie,过期时间与 token 一致
|
||||
// c.SetCookie("token", token, int(claims.ExpiresAt.Unix()-claims.IssuedAt.Unix()), "/", "", false, true)
|
||||
}
|
||||
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// AdminRequired 检查用户是否为管理员
|
||||
func AdminRequired() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
role, exists := c.Get("role")
|
||||
if !exists || role != "admin" {
|
||||
c.JSON(http.StatusForbidden, gin.H{"error": "需要管理员权限"})
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
c.Next()
|
||||
}
|
||||
}
|
62
internal/middleware/error.go
Normal file
62
internal/middleware/error.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"licserver/internal/utils"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func ErrorHandler() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
c.Next()
|
||||
|
||||
// 只处理第一个错误
|
||||
if len(c.Errors) > 0 {
|
||||
err := c.Errors[0].Err
|
||||
var statusCode int
|
||||
var response utils.ErrorResponse
|
||||
|
||||
switch err {
|
||||
case utils.ErrUnauthorized:
|
||||
statusCode = http.StatusUnauthorized
|
||||
response = utils.ErrorResponse{
|
||||
Code: 401,
|
||||
Message: "未授权的访问",
|
||||
Detail: err.Error(),
|
||||
}
|
||||
case utils.ErrForbidden:
|
||||
statusCode = http.StatusForbidden
|
||||
response = utils.ErrorResponse{
|
||||
Code: 403,
|
||||
Message: "禁止访问",
|
||||
Detail: err.Error(),
|
||||
}
|
||||
case utils.ErrNotFound:
|
||||
statusCode = http.StatusNotFound
|
||||
response = utils.ErrorResponse{
|
||||
Code: 404,
|
||||
Message: "资源不存在",
|
||||
Detail: err.Error(),
|
||||
}
|
||||
case utils.ErrInvalidInput:
|
||||
statusCode = http.StatusBadRequest
|
||||
response = utils.ErrorResponse{
|
||||
Code: 400,
|
||||
Message: "无效的输入",
|
||||
Detail: err.Error(),
|
||||
}
|
||||
default:
|
||||
statusCode = http.StatusInternalServerError
|
||||
response = utils.ErrorResponse{
|
||||
Code: 500,
|
||||
Message: "服务器内部错误",
|
||||
Detail: err.Error(),
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(statusCode, response)
|
||||
c.Abort()
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user