改进 路由和 http ctx

This commit is contained in:
Twilight 2024-06-13 15:36:51 +08:00
parent bc4e145689
commit 57662079f6
17 changed files with 130 additions and 104 deletions

1
go.mod
View File

@ -6,6 +6,7 @@ require (
ariga.io/atlas v0.23.0
entgo.io/ent v0.13.1
github.com/MicahParks/keyfunc/v3 v3.3.3
github.com/gin-contrib/zap v1.1.3
github.com/gin-gonic/gin v1.10.0
github.com/golang-jwt/jwt/v5 v5.2.1
github.com/golang-migrate/migrate/v4 v4.17.1

2
go.sum
View File

@ -61,6 +61,8 @@ github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy
github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-contrib/zap v1.1.3 h1:9e/U9fYd4/OBfmSEBs5hHZq114uACn7bpuzvCkcJySA=
github.com/gin-contrib/zap v1.1.3/go.mod h1:+BD/6NYZKJyUpqVoJEvgeq9GLz8pINEQvak9LHNOTSE=
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=

View File

@ -15,5 +15,5 @@ var (
)
func init() {
panic("ent not impl, if impl, uncommit this line")
//panic("ent not impl, if impl, uncommit this line")
}

View File

@ -1,13 +1 @@
package access
import (
"framework_v2/internal/providers"
"github.com/gin-gonic/gin"
)
type User providers.JwtIDToken
type Metadata struct {
Http *gin.Context
User User
}

View File

@ -2,6 +2,7 @@ package cmd
import (
"framework_v2/internal/access"
internalHttp "framework_v2/internal/http"
"framework_v2/internal/providers"
"github.com/spf13/cobra"
)
@ -12,12 +13,12 @@ var httpCommand = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
providers.InitConfig()
providers.InitLogger()
providers.InitEnt()
providers.InitRedis()
//providers.InitEnt()
//providers.InitRedis()
providers.InitJwksRefresh()
providers.InitAsynQClient()
providers.InitGin()
providers.InitApiRoutes()
internalHttp.InitHttp()
StartHttp()
},

View File

@ -0,0 +1,10 @@
package consts
import (
"github.com/gin-gonic/gin"
)
type Metadata struct {
Http *gin.Context
User *UserTokenInfo
}

24
internal/consts/user.go Normal file
View File

@ -0,0 +1,24 @@
package consts
type UserTokenInfo struct {
Exp int `json:"exp"`
Iat int `json:"iat"`
AuthTime int `json:"auth_time"`
Jti string `json:"jti"`
Iss string `json:"iss"`
Aud string `json:"aud"`
Sub string `json:"sub"`
Typ string `json:"typ"`
Azp string `json:"azp"`
SessionState string `json:"session_state"`
AtHash string `json:"at_hash"`
Acr string `json:"acr"`
Sid string `json:"sid"`
EmailVerified bool `json:"email_verified"`
Name string `json:"name"`
PreferredUsername string `json:"preferred_username"`
GivenName string `json:"given_name"`
FamilyName string `json:"family_name"`
Email string `json:"email"`
Groups []string `json:"groups"`
}

View File

@ -1,8 +0,0 @@
package user
import (
"framework_v2/internal/access"
)
func CurrentUser(metadata *access.Metadata) {
}

View File

@ -0,0 +1,13 @@
package user
import (
"framework_v2/internal/consts"
"github.com/gin-gonic/gin"
"net/http"
)
func CurrentUser(req *consts.Metadata) {
req.Http.JSON(http.StatusOK, gin.H{
"req": req.User,
})
}

14
internal/http/http.go Normal file
View File

@ -0,0 +1,14 @@
package http
import (
"framework_v2/internal/access"
"framework_v2/internal/http/routes"
)
func InitHttp() {
if access.Router == nil {
panic("You must call InitGin() before InitHttp()")
}
routes.InitApiRoutes()
}

View File

@ -1,6 +1,6 @@
package providers
package routes
import "framework_v2/internal/controllers/user"
import "framework_v2/internal/http/controllers/user"
func InitApiRoutes() {
HandleRoute(GET, "/", user.CurrentUser)

View File

@ -0,0 +1,45 @@
package routes
import (
"framework_v2/internal/access"
"framework_v2/internal/consts"
"github.com/gin-gonic/gin"
)
type httpMethod int
var httpMethodStr = []string{"GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"}
func (h httpMethod) String() string {
return httpMethodStr[h-1]
}
const (
GET httpMethod = iota + 1
POST
PUT
DELETE
PATCH
HEAD
OPTIONS
)
type HandlerFunc func(metadata *consts.Metadata)
func HandleRoute(method httpMethod, relativePath string, controller HandlerFunc, middlewares ...gin.HandlerFunc) {
access.Router.Handle(method.String(), relativePath, func(c *gin.Context) {
for _, middleware := range middlewares {
middleware(c)
}
handleWithMetadata(c, controller)
})
}
func handleWithMetadata(c *gin.Context, controller HandlerFunc) {
var metadata = &consts.Metadata{
Http: c,
}
controller(metadata)
}

View File

@ -2,48 +2,16 @@ package providers
import (
"framework_v2/internal/access"
ginzap "github.com/gin-contrib/zap"
"github.com/gin-gonic/gin"
"time"
)
func InitGin() {
access.Router = gin.Default()
access.Router.Use(gin.Recovery())
}
type httpMethod int
var httpMethodStr = []string{"GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"}
func (h httpMethod) String() string {
return httpMethodStr[h-1]
}
const (
GET httpMethod = iota + 1
POST
PUT
DELETE
PATCH
HEAD
OPTIONS
)
type HandlerFunc func(metadata *access.Metadata)
func HandleRoute(method httpMethod, relativePath string, controller HandlerFunc, middlewares ...gin.HandlerFunc) {
access.Router.Handle(method.String(), relativePath, func(c *gin.Context) {
for _, middleware := range middlewares {
middleware(c)
}
handleWithMetadata(c, controller)
})
}
func handleWithMetadata(c *gin.Context, controller HandlerFunc) {
var metadata = &access.Metadata{
Http: c,
}
controller(metadata)
gin.SetMode(gin.ReleaseMode)
access.Router = gin.New()
access.Router.Use(gin.Recovery(), ginzap.Ginzap(access.Logger, time.RFC3339, true))
access.Router.Use(ginzap.RecoveryWithZap(access.Logger, true))
}

View File

@ -2,6 +2,7 @@ package interceptor
import (
"context"
"framework_v2/internal/consts"
"framework_v2/internal/providers"
"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/auth"
"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging"
@ -17,10 +18,10 @@ func JwtAuth(ctx context.Context) (context.Context, error) {
}
sub := "anonymous"
var jwtIdToken *providers.JwtIDToken
var jwtIdToken *consts.UserTokenInfo
if providers.Config.DebugMode.Enable {
jwtIdToken = &providers.JwtIDToken{
jwtIdToken = &consts.UserTokenInfo{
Sub: sub,
}
} else {

View File

@ -3,6 +3,7 @@ package providers
import (
"context"
"errors"
"framework_v2/internal/consts"
"github.com/MicahParks/keyfunc/v3"
"github.com/golang-jwt/jwt/v5"
"time"
@ -12,29 +13,6 @@ var refreshRate = 1 * time.Hour
var Jwks keyfunc.Keyfunc
type JwtIDToken struct {
Exp int `json:"exp"`
Iat int `json:"iat"`
AuthTime int `json:"auth_time"`
Jti string `json:"jti"`
Iss string `json:"iss"`
Aud string `json:"aud"`
Sub string `json:"sub"`
Typ string `json:"typ"`
Azp string `json:"azp"`
SessionState string `json:"session_state"`
AtHash string `json:"at_hash"`
Acr string `json:"acr"`
Sid string `json:"sid"`
EmailVerified bool `json:"email_verified"`
Name string `json:"name"`
PreferredUsername string `json:"preferred_username"`
GivenName string `json:"given_name"`
FamilyName string `json:"family_name"`
Email string `json:"email"`
Groups []string `json:"groups"`
}
var (
ErrJWKSNotInitialized = errors.New("JWKS is not initialized")
)
@ -73,12 +51,12 @@ func ParseJWT(jwtB64 string) (*jwt.Token, error) {
return token, err
}
func GetAuthFromCtx(ctx context.Context) *JwtIDToken {
func GetAuthFromCtx(ctx context.Context) *consts.UserTokenInfo {
auth := ctx.Value("auth")
if auth == nil {
return nil
}
return auth.(*JwtIDToken)
return auth.(*consts.UserTokenInfo)
}

View File

@ -1,11 +0,0 @@
package providers
func (*JwtIDToken) InGroup(user *JwtIDToken, groupName string) bool {
for _, g := range user.Groups {
if g == groupName {
return true
}
}
return false
}