2025-02-19 21:52:33 +08:00
|
|
|
package admin
|
|
|
|
|
|
|
|
import (
|
2025-02-21 00:50:06 +08:00
|
|
|
"encoding/hex"
|
2025-02-19 21:52:33 +08:00
|
|
|
"errors"
|
|
|
|
"net/http"
|
|
|
|
"time"
|
|
|
|
|
2025-02-21 00:50:06 +08:00
|
|
|
"git.pyer.club/kingecg/gohttpd/model"
|
2025-02-19 21:52:33 +08:00
|
|
|
"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{
|
2025-02-21 00:50:06 +08:00
|
|
|
Name: "token",
|
|
|
|
Value: token,
|
|
|
|
Path: "/",
|
|
|
|
// HttpOnly: true,
|
|
|
|
// Secure: true,
|
2025-02-19 21:52:33 +08:00
|
|
|
SameSite: http.SameSiteStrictMode,
|
|
|
|
Expires: time.Now().Add(time.Hour * 24 * 7),
|
|
|
|
})
|
2025-02-21 00:50:06 +08:00
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
|
|
|
|
w.Write(server.NewSuccessResult("Login success"))
|
|
|
|
return
|
2025-02-19 21:52:33 +08:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
w.WriteHeader(http.StatusForbidden)
|
2025-02-21 00:50:06 +08:00
|
|
|
resp := server.NewErrorResult(errors.New("not allowed user/password"))
|
2025-02-19 21:52:33 +08:00
|
|
|
w.Write(resp)
|
2025-02-21 00:50:06 +08:00
|
|
|
return
|
2025-02-19 21:52:33 +08:00
|
|
|
}
|
2025-02-21 00:50:06 +08:00
|
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
|
|
w.Write(server.NewErrorResult(errors.New("not allowed user/password")))
|
2025-02-19 21:52:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// 实现非对称加密
|
|
|
|
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) {
|
2025-02-21 00:50:06 +08:00
|
|
|
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)
|
2025-02-19 21:52:33 +08:00
|
|
|
}
|
|
|
|
//去除末尾13个字节
|
2025-02-21 00:50:06 +08:00
|
|
|
plaintext = plaintext[1 : len(plaintext)-13]
|
2025-02-19 21:52:33 +08:00
|
|
|
return string(plaintext), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// 生成token
|
|
|
|
func GenerateToken(username string) (string, error) {
|
|
|
|
// jwt token
|
2025-02-21 00:50:06 +08:00
|
|
|
jwtConfig := model.GetConfig().Admin.Jwt
|
2025-02-19 21:52:33 +08:00
|
|
|
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))
|
|
|
|
}
|