package api import ( "auth_service/database" "auth_service/model" "encoding/json" "fmt" "maps" "net/http" "time" "github.com/golang-jwt/jwt/v5" ) const defaultsecretkey = "secret" func createJWT(secretKey string, data map[string]any, ttl time.Duration) (string, error) { claims := jwt.MapClaims{ "exp": time.Now().Add(ttl).Unix(), "iat": time.Now().Unix(), "nbf": time.Now().Unix(), } maps.Copy(claims, data) token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) signedToken, err := token.SignedString([]byte(secretKey)) if err != nil { return "", nil } return signedToken, nil } func VerifyJWT(tokenString string, secretKey string) (map[string]any, error) { token, e := jwt.Parse( tokenString, func(token *jwt.Token) (any, error) { if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("unexpexted signing method: %v", token.Header["alg"]) } return []byte(secretKey), nil }, ) if e != nil { return nil, fmt.Errorf("token validation failed: %w", e) } if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid { result := make(map[string]any) for key, value := range claims { if key == "exp" || key == "iat" || key == "nbf" { continue } result[key] = value } return result, nil } return nil, fmt.Errorf("invalid token") } func Token(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "application/json") var request model.TokenRequest decoder := json.NewDecoder(req.Body) decoder.Decode(&request) dbuser, e := database.GetUserByUsername(request.Username) if e != nil { fmt.Fprintf(w, "{\"status\":403,\"error\":\"%v\"}", e) return } if dbuser.Password == request.Password { responseUser := model.UserResponse{ Id: dbuser.Id, Username: dbuser.Username, Email: dbuser.Email, Group: dbuser.Group, IsSuperuser: dbuser.IsSuperuser, } responseUserMarshal, _ := json.Marshal(responseUser) responseUserUnmarshal := make(map[string]any) json.Unmarshal(responseUserMarshal, &responseUserUnmarshal) token, _ := createJWT(defaultsecretkey, responseUserUnmarshal, time.Duration(24*time.Hour)) fmt.Fprintf(w, "{\"token\":\"%s\"}", token) return } fmt.Fprintf(w, "{\"status\":\"403\"}") } func VerifyToken(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "application/json") var request model.Token decoder := json.NewDecoder(req.Body) decoder.Decode(&request) _, e := VerifyJWT(request.Token, defaultsecretkey) if e != nil { fmt.Fprintf(w, "{\"status\":403}") return } fmt.Fprintf(w, "{\"status\":200}") }