🏗️ microservice fabric splitting

This commit is contained in:
2024-12-24 00:38:41 +08:00
parent 462e811742
commit 89d64336f5
311 changed files with 18384 additions and 2428 deletions

View File

@@ -0,0 +1,32 @@
package middleware
import (
"github.com/zeromicro/go-zero/core/logx"
"net/http"
"schisandra-album-cloud-microservices/common/errors"
"schisandra-album-cloud-microservices/common/xhttp"
"strconv"
"time"
)
func AuthorizationMiddleware(w http.ResponseWriter, r *http.Request) {
expireAtStr := r.Header.Get("X-Expire-At")
if expireAtStr == "" {
xhttp.JsonBaseResponseCtx(r.Context(), w, errors.New(http.StatusForbidden, "unauthorized"))
return
}
expireAtInt, err := strconv.ParseInt(expireAtStr, 10, 64)
if err != nil {
logx.Errorf("Failed to parse X-Expire-At: %v", err)
xhttp.JsonBaseResponseCtx(r.Context(), w, errors.New(http.StatusForbidden, "unauthorized"))
return
}
expireAt := time.Unix(expireAtInt, 0)
currentTime := time.Now()
remainingTime := expireAt.Sub(currentTime)
if remainingTime < time.Minute*5 {
xhttp.JsonBaseResponseCtx(r.Context(), w, errors.New(http.StatusUnauthorized, "token expired"))
return
}
}

View File

@@ -0,0 +1,18 @@
package middleware
import (
"github.com/casbin/casbin/v2"
"net/http"
"schisandra-album-cloud-microservices/common/constant"
"schisandra-album-cloud-microservices/common/errors"
"schisandra-album-cloud-microservices/common/xhttp"
)
func CasbinMiddleware(w http.ResponseWriter, r *http.Request, casbin *casbin.SyncedCachedEnforcer) {
userId := r.Header.Get(constant.UID_HEADER_KEY)
correct, err := casbin.Enforce(userId, r.URL.Path, r.Method)
if err != nil || !correct {
xhttp.JsonBaseResponseCtx(r.Context(), w, errors.New(http.StatusForbidden, "forbidden"))
return
}
}

View File

@@ -0,0 +1,13 @@
package middleware
import "net/http"
func CORSMiddleware() func(http.Header) {
return func(header http.Header) {
header.Set("Access-Control-Allow-Origin", "*")
header.Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, PATCH")
header.Set("Access-Control-Expose-Headers", "Content-Length, Content-Type")
header.Set("Access-Control-Allow-Headers", "Content-Type,Authorization,Accept-Language,Origin,X-Content-Security,X-UID,X-Nonce,X-Expire-At")
header.Set("Access-Control-Allow-Credentials", "true")
}
}

View File

@@ -0,0 +1,23 @@
package middleware
import (
"net/http"
"os"
"path/filepath"
"schisandra-album-cloud-microservices/common/i18n"
"golang.org/x/text/language"
)
func I18nMiddleware(next http.HandlerFunc) http.HandlerFunc {
cwd, err := os.Getwd()
if err != nil {
panic(err)
}
zhPath := filepath.Join(cwd, "/resources/language/", "active.zh.toml")
enPath := filepath.Join(cwd, "/resources/language/", "active.en.toml")
return i18n.NewI18nMiddleware([]language.Tag{
language.English,
language.Chinese,
}, []string{enPath, zhPath}).Handle(next)
}

View File

@@ -0,0 +1,32 @@
package middleware
import (
"github.com/redis/go-redis/v9"
"net/http"
"schisandra-album-cloud-microservices/common/constant"
"schisandra-album-cloud-microservices/common/errors"
"schisandra-album-cloud-microservices/common/xhttp"
"time"
)
func NonceMiddleware(w http.ResponseWriter, r *http.Request, redisClient *redis.Client) {
nonce := r.Header.Get("X-Nonce")
if nonce == "" {
xhttp.JsonBaseResponseCtx(r.Context(), w, errors.New(http.StatusBadRequest, "bad request!"))
return
}
if len(nonce) != 32 {
xhttp.JsonBaseResponseCtx(r.Context(), w, errors.New(http.StatusBadRequest, "bad request!"))
return
}
result := redisClient.Get(r.Context(), constant.SystemApiNoncePrefix+nonce).Val()
if result != "" {
xhttp.JsonBaseResponseCtx(r.Context(), w, errors.New(http.StatusBadRequest, "bad request!"))
return
}
err := redisClient.Set(r.Context(), constant.SystemApiNoncePrefix+nonce, nonce, time.Minute*1).Err()
if err != nil {
xhttp.JsonBaseResponseCtx(r.Context(), w, errors.New(http.StatusInternalServerError, "internal server error!"))
return
}
}

View File

@@ -0,0 +1,13 @@
package middleware
import "net/http"
func SecurityHeadersMiddleware(r *http.Request) {
r.Header.Set("X-Frame-Options", "DENY")
r.Header.Set("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';")
r.Header.Set("X-XSS-Protection", "1; mode=block")
r.Header.Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
r.Header.Set("Referrer-Policy", "strict-origin")
r.Header.Set("X-Content-Type-Options", "nosniff")
r.Header.Set("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()")
}

View File

@@ -0,0 +1,14 @@
package middleware
import (
"net/http"
"schisandra-album-cloud-microservices/common/errors"
"schisandra-album-cloud-microservices/common/xhttp"
)
func UnauthorizedCallbackMiddleware() func(w http.ResponseWriter, r *http.Request, err error) {
return func(w http.ResponseWriter, r *http.Request, err error) {
xhttp.JsonBaseResponseCtx(r.Context(), w, errors.New(http.StatusUnauthorized, err.Error()))
return
}
}

View File

@@ -0,0 +1,14 @@
package middleware
import (
"net/http"
"schisandra-album-cloud-microservices/common/errors"
"schisandra-album-cloud-microservices/common/xhttp"
)
func UnsignedCallbackMiddleware() func(w http.ResponseWriter, r *http.Request, next http.Handler, strict bool, code int) {
return func(w http.ResponseWriter, r *http.Request, next http.Handler, strict bool, code int) {
xhttp.JsonBaseResponseCtx(r.Context(), w, errors.New(http.StatusForbidden, "Unsigned callback not allowed"))
return
}
}