🏗️ microservice fabric splitting
This commit is contained in:
32
common/middleware/authorization_middleware.go
Normal file
32
common/middleware/authorization_middleware.go
Normal 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
|
||||
}
|
||||
}
|
18
common/middleware/casbin_middleware.go
Normal file
18
common/middleware/casbin_middleware.go
Normal 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
|
||||
}
|
||||
}
|
13
common/middleware/cors_middleware.go
Normal file
13
common/middleware/cors_middleware.go
Normal 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")
|
||||
}
|
||||
}
|
23
common/middleware/i18n_middleware.go
Normal file
23
common/middleware/i18n_middleware.go
Normal 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)
|
||||
}
|
32
common/middleware/nonce_middleware.go
Normal file
32
common/middleware/nonce_middleware.go
Normal 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
|
||||
}
|
||||
}
|
13
common/middleware/security_headers_middleware.go
Normal file
13
common/middleware/security_headers_middleware.go
Normal 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=()")
|
||||
}
|
14
common/middleware/unauthorized_callback_middleware.go
Normal file
14
common/middleware/unauthorized_callback_middleware.go
Normal 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
|
||||
}
|
||||
}
|
14
common/middleware/unsigned_callback_middleware.go
Normal file
14
common/middleware/unsigned_callback_middleware.go
Normal 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
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user