Skip to content

Commit d7889a6

Browse files
authored
Merge pull request #13 from dingdinglz/dev
✨ feat(登录): 完成webui登录功能
2 parents 070e932 + fe81a34 commit d7889a6

18 files changed

+608
-1
lines changed

appconfig/config.go

+2
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,6 @@ func ConfigInit() {
3030
tool.DictoryCreateN(filepath.Join(rootPath, "data", "plugin"))
3131
tool.DictoryCreateN(filepath.Join(rootPath, "data", "plugin", "source"))
3232
tool.DictoryCreateN(filepath.Join(rootPath, "data", "plugin"))
33+
34+
JWTSecret = GenerateRandString(10)
3335
}

appconfig/global.go

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ var (
1010
AppConfigVar AppConfig
1111
Version string = "v2 beta"
1212
BotConfigVar BotConfig
13+
JWTSecret string
1314
)
1415

1516
type AppConfig struct {

appconfig/tool.go

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package appconfig
2+
3+
import (
4+
"math/rand"
5+
)
6+
7+
// 生成一个指定长度的随机字符串,内容包括26个字母和10个数字
8+
func GenerateRandString(n int) string {
9+
var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
10+
b := make([]rune, n)
11+
for i := range b {
12+
b[i] = letterRunes[rand.Intn(len(letterRunes))]
13+
}
14+
return string(b)
15+
}

appconfig/tool_test.go

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package appconfig
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
)
7+
8+
func TestGenerateRandString(t *testing.T) {
9+
fmt.Println(GenerateRandString(10))
10+
}

database/init.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func DatabaseInit() {
2222
tool.ErrorOut("database", "open error", err)
2323
panic(err.Error())
2424
}
25-
DB.AutoMigrate(&KeyWordTable{}, &OpenTable{}, &StopTable{}, &MessageTable{}, &PluginData{}, &StarTable{}, &GithubHookTable{})
25+
DB.AutoMigrate(&KeyWordTable{}, &OpenTable{}, &StopTable{}, &MessageTable{}, &PluginData{}, &StarTable{}, &GithubHookTable{}, &UserTable{})
2626

2727
// 清空message表的内容,message表用于存seq与message对应,便于取撤回内容
2828
DB.Delete(&MessageTable{}, "1=1")

database/tables.go

+10
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,13 @@ type GithubHookTable struct {
6565
func (GithubHookTable) TableName() string {
6666
return "github"
6767
}
68+
69+
type UserTable struct {
70+
ID uint
71+
Username string
72+
Password string
73+
}
74+
75+
func (UserTable) TableName() string {
76+
return "user"
77+
}

database/tool.go

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package database
2+
3+
import (
4+
"crypto/md5"
5+
"fmt"
6+
"io"
7+
)
8+
9+
func md5Generate(text string) string {
10+
h := md5.New()
11+
io.WriteString(h, text)
12+
return fmt.Sprintf("%x", h.Sum(nil))
13+
}

database/user.go

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package database
2+
3+
import "errors"
4+
5+
func UserExist(username string) bool {
6+
var i int64
7+
DB.Model(&UserTable{}).Where("username = ?", username).Count(&i)
8+
return i != 0
9+
}
10+
11+
func UserNew(username string, password string) error {
12+
if UserExist(username) {
13+
return errors.New("用户已存在")
14+
}
15+
var i UserTable
16+
i.Username = username
17+
i.Password = md5Generate(password)
18+
DB.Create(&i)
19+
return nil
20+
}
21+
22+
func UserLogin(username string, password string) bool {
23+
if !UserExist(username) {
24+
return false
25+
}
26+
var i UserTable
27+
DB.Model(&UserTable{}).Where("username = ?", username).First(&i)
28+
return i.Password == md5Generate(password)
29+
}

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ require (
2121
github.com/go-sql-driver/mysql v1.7.0 // indirect
2222
github.com/gofiber/template v1.8.3 // indirect
2323
github.com/gofiber/utils v1.1.0 // indirect
24+
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
2425
github.com/google/uuid v1.5.0 // indirect
2526
github.com/jinzhu/inflection v1.0.0 // indirect
2627
github.com/jinzhu/now v1.1.5 // indirect

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ github.com/gofiber/template/html/v2 v2.1.2 h1:wkK/mYJ3nIhongTkG3t0QgV4ADdgOYJYVS
2222
github.com/gofiber/template/html/v2 v2.1.2/go.mod h1:E98Z/FzvpaSib06aWEgYk6GXNf3ctoyaJH8yW5ay5ak=
2323
github.com/gofiber/utils v1.1.0 h1:vdEBpn7AzIUJRhe+CiTOJdUcTg4Q9RK+pEa0KPbLdrM=
2424
github.com/gofiber/utils v1.1.0/go.mod h1:poZpsnhBykfnY1Mc0KeEa6mSHrS3dV0+oBWyeQmb2e0=
25+
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
26+
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
2527
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
2628
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
2729
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=

route/formal.go

+4
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,7 @@ func GithubRoute(ctx *fiber.Ctx) error {
106106
pageMap["Githubs"] = database.GithubWebhookGetAll()
107107
return ctx.Render("github", pageMap, "layout")
108108
}
109+
110+
func LoginRoute(ctx *fiber.Ctx) error {
111+
return ctx.Render("login", GenerateRenderMap("login"))
112+
}

route/init.go

+13
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"os"
66
"path/filepath"
77

8+
"github.com/dingdinglz/dingbot/appconfig"
9+
"github.com/dingdinglz/dingbot/database"
810
"github.com/dingdinglz/dingbot/tool"
911
"github.com/gofiber/fiber/v2"
1012
)
@@ -13,6 +15,8 @@ func InitRoute(c *fiber.Ctx) error {
1315
port := c.FormValue("port", "")
1416
databaseType := c.FormValue("database", "")
1517
source := c.FormValue("source", "")
18+
user := c.FormValue("username", "")
19+
pass := c.FormValue("password", "")
1620
if port == "" {
1721
return JsonMessage(c, 1, "port不能为空!")
1822
}
@@ -22,8 +26,17 @@ func InitRoute(c *fiber.Ctx) error {
2226
if source == "" {
2327
return JsonMessage(c, 1, "source不能为空!")
2428
}
29+
if user == "" {
30+
return JsonMessage(c, 1, "username不能为空!")
31+
}
32+
if pass == "" {
33+
return JsonMessage(c, 1, "password不能为空!")
34+
}
2535
configText, _ := json.Marshal(fiber.Map{"port": tool.StringToInt(port), "database": databaseType, "source": source})
2636
rootPath, _ := os.Getwd()
2737
os.WriteFile(filepath.Join(rootPath, "data", "config.json"), configText, os.ModePerm)
38+
appconfig.ConfigInit()
39+
database.DatabaseInit()
40+
database.UserNew(user, pass)
2841
return JsonMessage(c, 0, "ok")
2942
}

route/jwt.go

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package route
2+
3+
import (
4+
"time"
5+
6+
"github.com/dingdinglz/dingbot/appconfig"
7+
"github.com/golang-jwt/jwt/v5"
8+
)
9+
10+
type UserJWTModel struct {
11+
Username string
12+
jwt.RegisteredClaims
13+
}
14+
15+
// jwtUserGenerate 生成jwt
16+
func jwtUserGenerate(user string) string {
17+
token := jwt.NewWithClaims(jwt.SigningMethodHS256, UserJWTModel{
18+
user,
19+
jwt.RegisteredClaims{
20+
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour * 24)),
21+
},
22+
})
23+
t, _ := token.SignedString([]byte(appconfig.JWTSecret))
24+
return t
25+
}
26+
27+
// jwtUserParse 解析jwt
28+
func jwtUserParse(tokenString string) (string, bool) {
29+
tokenAfter, e := jwt.ParseWithClaims(tokenString, &UserJWTModel{}, func(token *jwt.Token) (interface{}, error) {
30+
return []byte(appconfig.JWTSecret), nil
31+
})
32+
if e != nil {
33+
return "", false
34+
}
35+
cliamAfter := tokenAfter.Claims.(*UserJWTModel)
36+
return cliamAfter.Username, true
37+
}

route/login.go

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package route
2+
3+
import (
4+
"time"
5+
6+
"github.com/dingdinglz/dingbot/database"
7+
"github.com/gofiber/fiber/v2"
8+
)
9+
10+
func ApiLoginRoute(c *fiber.Ctx) error {
11+
if c.FormValue("username", "") == "" || c.FormValue("password", "") == "" {
12+
return JsonMessage(c, 1, "用户名或密码不能为空!")
13+
}
14+
ok := database.UserLogin(c.FormValue("username"), c.FormValue("password"))
15+
if !ok {
16+
return JsonMessage(c, 2, "用户名或密码错误!")
17+
}
18+
c.Cookie(&fiber.Cookie{Name: "token",
19+
Value: jwtUserGenerate(c.FormValue("username")),
20+
Expires: time.Now().Add(24 * time.Hour)})
21+
return JsonMessage(c, 0, "ok")
22+
}

route/middleware.go

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package route
2+
3+
import "github.com/gofiber/fiber/v2"
4+
5+
func LoginMiddleware(c *fiber.Ctx) error {
6+
if c.Path() == "/login" || c.Path() == "/api/login" {
7+
return c.Next()
8+
}
9+
t := c.Cookies("token", "")
10+
if t == "" {
11+
return c.Redirect("/login")
12+
}
13+
user, ok := jwtUserParse(t)
14+
if !ok {
15+
return c.Redirect("/login")
16+
}
17+
c.Locals("user", user)
18+
return c.Next()
19+
}

server.go

+3
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ func ServerInitRun() {
5050
}
5151

5252
func ServerCommonRun() {
53+
appconfig.MainServer.Use(route.LoginMiddleware)
54+
appconfig.MainServer.Get("/login", route.LoginRoute)
5355
appconfig.MainServer.Get("/", route.IndexRoute)
5456
appconfig.MainServer.Get("/key", route.KeyWordRoute)
5557
appconfig.MainServer.Get("/plugin-edit/:name", route.PluginEditRoute)
@@ -60,6 +62,7 @@ func ServerCommonRun() {
6062
appconfig.MainServer.Post("/github/webhook", route.GithubWebhookRoute)
6163

6264
apiRoute := appconfig.MainServer.Group("/api")
65+
apiRoute.Post("/login", route.ApiLoginRoute)
6366

6467
apiGetRoute := apiRoute.Group("/get")
6568
apiGetRoute.Get("/bot", route.GetBotConfigRoute)

0 commit comments

Comments
 (0)