feat: openid login

This commit is contained in:
zzw
2026-09-02 17:37:12 +08:00
parent 540f74f9b7
commit bb14f9e324
38 changed files with 1627 additions and 1091 deletions
+91 -24
View File
@@ -14,21 +14,41 @@ import (
type ctxKey string
const (
CtxUserId ctxKey = "X-User-Id"
CtxUserName ctxKey = "X-User-Name"
CtxRefresh ctxKey = "X-Refresh"
CtxClientIP ctxKey = "X-Client-Ip"
CtxUserAgent ctxKey = "X-User-Agent"
CtxUserId ctxKey = "X-User-Id"
CtxUserName ctxKey = "X-User-Name"
CtxRefresh ctxKey = "X-Refresh"
CtxClientIP ctxKey = "X-Client-Ip"
CtxUserAgent ctxKey = "X-User-Agent"
CtxClientCode ctxKey = "X-Client-Code"
CtxSaleId ctxKey = "X-Sale-Id"
CtxSaleName ctxKey = "X-Sale-Name"
CtxSaleMobile ctxKey = "X-Sale-Mobile"
CtxSaleProvince ctxKey = "X-Sale-Province"
CtxStoreId ctxKey = "X-Store-Id"
CtxStoreName ctxKey = "X-Store-Name"
CtxGroupId ctxKey = "X-Group-Id"
CtxGroupName ctxKey = "X-Group-Name"
CtxUserType ctxKey = "X-User-Type"
)
type UserInfo struct {
ID int64
Name string
RawUID string
Refresh string
ClientIP string
UserAgent string
Valid bool
ID int64
Name string
RawUID string
Refresh string
ClientIP string
UserAgent string
Type string
ClientCode string
SaleId string
SaleName string
SaleMobile string
SaleProvince string
StoreId string
StoreName string
GroupId string
GroupName string
Valid bool
}
func GetUserInfo(ctx context.Context) UserInfo {
@@ -37,13 +57,33 @@ func GetUserInfo(ctx context.Context) UserInfo {
refresh, _ := ctx.Value(CtxRefresh).(string)
clientIP, _ := ctx.Value(CtxClientIP).(string)
userAgent, _ := ctx.Value(CtxUserAgent).(string)
userType, _ := ctx.Value(CtxUserType).(string)
clientCode, _ := ctx.Value(CtxClientCode).(string)
saleId, _ := ctx.Value(CtxSaleId).(string)
saleName, _ := ctx.Value(CtxSaleName).(string)
saleMobile, _ := ctx.Value(CtxSaleMobile).(string)
saleProvince, _ := ctx.Value(CtxSaleProvince).(string)
storeId, _ := ctx.Value(CtxStoreId).(string)
storeName, _ := ctx.Value(CtxStoreName).(string)
groupId, _ := ctx.Value(CtxGroupId).(string)
groupName, _ := ctx.Value(CtxGroupName).(string)
info := UserInfo{
RawUID: rawUID,
Name: name,
Refresh: refresh,
ClientIP: clientIP,
UserAgent: userAgent,
RawUID: rawUID,
Name: name,
Refresh: refresh,
ClientIP: clientIP,
UserAgent: userAgent,
Type: userType,
ClientCode: clientCode,
SaleId: saleId,
SaleName: saleName,
SaleMobile: saleMobile,
SaleProvince: saleProvince,
StoreId: storeId,
StoreName: storeName,
GroupId: groupId,
GroupName: groupName,
}
if rawUID == "" {
return info
@@ -58,7 +98,6 @@ func GetUserInfo(ctx context.Context) UserInfo {
return info
}
// getRealClientIP 获取真实客户端IP,优先 XForwardedFor,其次 XRealIP,最后 RemoteAddr
func getRealClientIP(r *http.Request) string {
xff := r.Header.Get("X-Forwarded-For")
if xff != "" {
@@ -79,10 +118,26 @@ func UserReadMiddleware(next http.HandlerFunc) http.HandlerFunc {
newCtx = context.WithValue(newCtx, CtxRefresh, r.Header.Get("X-Refresh"))
newCtx = context.WithValue(newCtx, CtxClientIP, getRealClientIP(r))
newCtx = context.WithValue(newCtx, CtxUserAgent, r.UserAgent())
newCtx = context.WithValue(newCtx, CtxUserType, r.Header.Get("X-User-Type"))
newCtx = context.WithValue(newCtx, CtxClientCode, r.Header.Get("X-Client-Code"))
newCtx = context.WithValue(newCtx, CtxSaleId, r.Header.Get("X-Sale-Id"))
newCtx = context.WithValue(newCtx, CtxSaleName, r.Header.Get("X-Sale-Name"))
newCtx = context.WithValue(newCtx, CtxSaleMobile, r.Header.Get("X-Sale-Mobile"))
newCtx = context.WithValue(newCtx, CtxSaleProvince, r.Header.Get("X-Sale-Province"))
newCtx = context.WithValue(newCtx, CtxStoreId, r.Header.Get("X-Store-Id"))
newCtx = context.WithValue(newCtx, CtxStoreName, r.Header.Get("X-Store-Name"))
newCtx = context.WithValue(newCtx, CtxGroupId, r.Header.Get("X-Group-Id"))
newCtx = context.WithValue(newCtx, CtxGroupName, r.Header.Get("X-Group-Name"))
next(w, r.WithContext(newCtx))
}
}
func setMDIfNotEmpty(md metadata.MD, key, value string) {
if value != utils.StringEmpty {
md.Set(key, value)
}
}
func UserClientInterceptor(ctx context.Context, method string, req, reply any, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
user := GetUserInfo(ctx)
md := metadata.New(map[string]string{})
@@ -92,15 +147,27 @@ func UserClientInterceptor(ctx context.Context, method string, req, reply any, c
md.Set("x-user-name", url.QueryEscape(user.Name))
}
if user.Refresh != utils.StringEmpty {
md.Set("x-refresh", user.Refresh)
}
if user.ClientIP != utils.StringEmpty {
md.Set("x-client-ip", user.ClientIP)
}
setMDIfNotEmpty(md, "x-refresh", user.Refresh)
setMDIfNotEmpty(md, "x-client-ip", user.ClientIP)
if user.UserAgent != utils.StringEmpty {
md.Set("x-user-agent", url.QueryEscape(user.UserAgent))
}
setMDIfNotEmpty(md, "x-user-type", user.Type)
setMDIfNotEmpty(md, "x-client-code", user.ClientCode)
setMDIfNotEmpty(md, "x-sale-id", user.SaleId)
if user.SaleName != utils.StringEmpty {
md.Set("x-sale-name", url.QueryEscape(user.SaleName))
}
setMDIfNotEmpty(md, "x-sale-mobile", user.SaleMobile)
setMDIfNotEmpty(md, "x-sale-province", user.SaleProvince)
setMDIfNotEmpty(md, "x-store-id", user.StoreId)
if user.StoreName != utils.StringEmpty {
md.Set("x-store-name", url.QueryEscape(user.StoreName))
}
setMDIfNotEmpty(md, "x-group-id", user.GroupId)
if user.GroupName != utils.StringEmpty {
md.Set("x-group-name", url.QueryEscape(user.GroupName))
}
ctx = metadata.NewOutgoingContext(ctx, md)
return invoker(ctx, method, req, reply, cc, opts...)