| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- package authbase
-
- import (
- "encoding/base64"
- "net/http"
- "strings"
- "time"
-
- "git.x2erp.com/qdy/go-base/config"
- "git.x2erp.com/qdy/go-base/ctx"
- "git.x2erp.com/qdy/go-base/logger"
- )
-
- // BasicAuth 简化的Basic认证中间件
- func BasicAuth(next http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if logger.IsDebug() {
- logger.Debug("BasicAuth中间件开始处理请求: %s %s", r.Method, r.URL.Path)
- }
- // 1. 检查认证头
- authHeader := r.Header.Get("Authorization")
- if authHeader == "" {
- if logger.IsDebug() {
- logger.Debug("认证头缺失,请求未授权: %s %s", r.Method, r.URL.Path)
- }
- unauthorized(w, "缺少认证信息")
- return
- }
-
- if logger.IsDebug() {
- displayHeader := authHeader
- if len(displayHeader) > 20 {
- displayHeader = displayHeader[:20] + "..."
- }
- logger.Debug("收到认证头: %s", displayHeader)
- }
-
- // 2. 检查Basic格式
- if !strings.HasPrefix(authHeader, "Basic ") {
- if logger.IsDebug() {
- displayHeader := authHeader
- if len(displayHeader) > 20 {
- displayHeader = displayHeader[:20] + "..."
- }
- logger.Debug("认证格式错误,需要Basic认证: %s", displayHeader)
- }
- unauthorized(w, "认证格式错误,请使用Basic认证")
- return
- }
-
- // 3. 解码凭证
- base64Creds := strings.TrimPrefix(authHeader, "Basic ")
- if logger.IsDebug() {
- logger.Debug("解码Base64凭证,长度: %d", len(base64Creds))
- }
- credsBytes, err := base64.StdEncoding.DecodeString(base64Creds)
- if err != nil {
- if logger.IsDebug() {
- logger.Debug("Base64解码失败: %v", err)
- }
- unauthorized(w, "认证信息解码失败")
- return
- }
-
- // 4. 分割用户名密码
- creds := string(credsBytes)
- if logger.IsDebug() {
- logger.Debug("解码后凭证长度: %d", len(creds))
- }
- parts := strings.SplitN(creds, ":", 2)
- if len(parts) != 2 {
- if logger.IsDebug() {
- logger.Debug("用户名密码格式错误,分割后部分数: %d", len(parts))
- }
- unauthorized(w, "用户名密码格式错误")
- return
- }
-
- username := parts[0]
- password := parts[1]
- if logger.IsDebug() {
- logger.Debug("提取用户名: %s,密码长度: %d", username, len(password))
- }
-
- // 5. 验证用户名密码
- if logger.IsDebug() {
- logger.Debug("开始验证用户名密码: %s", username)
- }
- userID, tenantID, ok := verifyCredentials(username, password)
- if !ok {
- if logger.IsDebug() {
- logger.Debug("用户名密码验证失败: %s", username)
- }
- unauthorized(w, "用户名或密码错误")
- return
- }
- if logger.IsDebug() {
- logger.Debug("用户名密码验证成功: userID=%s, tenantID=%s", userID, tenantID)
- }
-
- // 6. 创建请求上下文
- traceID := r.Header.Get("X-Trace-ID")
- if traceID == "" {
- // 生成简单的时间戳追踪ID
- traceID = time.Now().Format("20060102150405.000")
- if logger.IsDebug() {
- logger.Debug("生成TraceID: %s", traceID)
- }
- } else if logger.IsDebug() {
- logger.Debug("使用请求中的TraceID: %s", traceID)
- }
-
- cfg := config.GetConfig()
-
- requestCtx := &ctx.RequestContext{
- ServiceName: cfg.GetServiceConfig().ServiceName,
- InstanceName: cfg.GetServiceConfig().InstanceName,
- TraceID: traceID,
- TenantID: tenantID,
- UserID: userID,
- Username: username,
- }
-
- if logger.IsDebug() {
- logger.Debug("创建请求上下文: service=%s, instance=%s, tenant=%s, user=%s",
- requestCtx.ServiceName, requestCtx.InstanceName, requestCtx.TenantID, requestCtx.UserID)
- }
-
- // 7. 保存到请求
- r = ctx.SaveContext(r, requestCtx)
-
- // 8. 继续处理
- if logger.IsDebug() {
- logger.Debug("BasicAuth中间件处理完成,继续下一个处理器")
- }
- next.ServeHTTP(w, r)
- })
- }
-
- // 验证用户名密码(简单示例)
- func verifyCredentials(username, password string) (userID, tenantID string, ok bool) {
- if logger.IsDebug() {
- logger.Debug("验证凭据,用户名: %s", username)
- }
-
- // 这里替换为你的实际验证逻辑
- cfg := config.GetConfig()
- sysUsername := cfg.GetServiceConfig().Username
- sysPassword := cfg.GetServiceConfig().Password
-
- if username == sysUsername && password == sysPassword {
- if logger.IsDebug() {
- logger.Debug("凭据验证成功,用户名匹配系统用户")
- }
- return sysUsername, "tenant-admin", true
- }
- if logger.IsDebug() {
- logger.Debug("凭据验证失败,用户名或密码不匹配")
- }
- return "", "", false
- }
|