package admin import ( "encoding/hex" "errors" "net/http" "time" "git.pyer.club/kingecg/gohttpd/model" "git.pyer.club/kingecg/gohttpd/server" "github.com/golang-jwt/jwt/v5" ) type LoginModel struct { Username string `json:"username"` Encrypt string `json:"password"` } func login(w http.ResponseWriter, r *http.Request) { ctx := r.Context() ctxData := ctx.Value(server.RequestCtxKey("data")).(map[string]interface{}) data, ok := ctxData["data"] if !ok { w.WriteHeader(http.StatusBadRequest) return } t := data.(LoginModel) if t.Username == "admin" { decryptText, _ := Decrypt(t.Encrypt) if decryptText == model.GetConfig().Admin.Password { token, err := GenerateToken(t.Username) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write(server.NewErrorResult(err)) return } http.SetCookie(w, &http.Cookie{ Name: "token", Value: token, Path: "/", // HttpOnly: true, // Secure: true, SameSite: http.SameSiteStrictMode, Expires: time.Now().Add(time.Hour * 24 * 7), }) w.WriteHeader(http.StatusOK) w.Write(server.NewSuccessResult("Login success")) return } } else { w.WriteHeader(http.StatusForbidden) resp := server.NewErrorResult(errors.New("not allowed user/password")) w.Write(resp) return } w.WriteHeader(http.StatusUnauthorized) w.Write(server.NewErrorResult(errors.New("not allowed user/password"))) } // 实现非对称加密 func Encrypt(plaintext string) (string, error) { ciphertext := make([]byte, len(plaintext)) for i := 0; i < len(plaintext); i++ { ciphertext[i] = plaintext[i] ^ 0xFF } return string(ciphertext), nil } // 实现非对称解密 func Decrypt(ciphertext string) (string, error) { plaintext := make([]byte, 1) cipbyte := []byte(ciphertext) // 每次取前2字节 for i := 0; i < len(cipbyte); i += 2 { d := cipbyte[i : i+2] // 转成16进制 dd, err := hex.DecodeString(string(d)) if err != nil { return "", err } // 异或 plaintext = append(plaintext, dd[0]^0xFF) } //去除末尾13个字节 plaintext = plaintext[1 : len(plaintext)-13] return string(plaintext), nil } // 生成token func GenerateToken(username string) (string, error) { // jwt token jwtConfig := model.GetConfig().Admin.Jwt secret := jwtConfig.Secret expire := jwtConfig.Expire issuer := jwtConfig.Issuer audience := jwtConfig.Audience claim := &jwt.RegisteredClaims{ ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Duration(expire) * time.Hour)), Issuer: issuer, Audience: []string{audience}, IssuedAt: jwt.NewNumericDate(time.Now()), Subject: username, } // 生成token token := jwt.NewWithClaims(jwt.SigningMethodHS256, claim) return token.SignedString([]byte(secret)) }