-
Notifications
You must be signed in to change notification settings - Fork 23
Not completed yet,continuing to work #18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 12 commits
9981366
deae913
582335b
bb437b6
3fcdf0a
15528b5
04a8538
869f0cd
1b8d4f1
8add0c4
3a19e2f
5de7e83
c628ee2
f2418df
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| module awesomeProject | ||
|
|
||
| go 1.23.1 | ||
|
|
||
| require ( | ||
| github.com/gin-gonic/gin v1.10.0 | ||
| gorm.io/driver/mysql v1.5.7 | ||
| gorm.io/gorm v1.25.12 | ||
| ) | ||
|
|
||
| require ( | ||
| github.com/bytedance/sonic v1.11.6 // indirect | ||
| github.com/bytedance/sonic/loader v0.1.1 // indirect | ||
| github.com/cloudwego/base64x v0.1.4 // indirect | ||
| github.com/cloudwego/iasm v0.2.0 // indirect | ||
| github.com/gabriel-vasile/mimetype v1.4.3 // indirect | ||
| github.com/gin-contrib/sse v0.1.0 // indirect | ||
| github.com/go-playground/locales v0.14.1 // indirect | ||
| github.com/go-playground/universal-translator v0.18.1 // indirect | ||
| github.com/go-playground/validator/v10 v10.20.0 // indirect | ||
| github.com/go-sql-driver/mysql v1.7.0 // indirect | ||
| github.com/goccy/go-json v0.10.2 // indirect | ||
| github.com/jinzhu/inflection v1.0.0 // indirect | ||
| github.com/jinzhu/now v1.1.5 // indirect | ||
| github.com/json-iterator/go v1.1.12 // indirect | ||
| github.com/klauspost/cpuid/v2 v2.2.7 // indirect | ||
| github.com/leodido/go-urn v1.4.0 // indirect | ||
| github.com/mattn/go-isatty v0.0.20 // indirect | ||
| github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect | ||
| github.com/modern-go/reflect2 v1.0.2 // indirect | ||
| github.com/pelletier/go-toml/v2 v2.2.2 // indirect | ||
| github.com/twitchyliquid64/golang-asm v0.15.1 // indirect | ||
| github.com/ugorji/go/codec v1.2.12 // indirect | ||
| golang.org/x/arch v0.8.0 // indirect | ||
| golang.org/x/crypto v0.23.0 // indirect | ||
| golang.org/x/net v0.25.0 // indirect | ||
| golang.org/x/sys v0.20.0 // indirect | ||
| golang.org/x/text v0.15.0 // indirect | ||
| google.golang.org/protobuf v1.34.1 // indirect | ||
| gopkg.in/yaml.v3 v3.0.1 // indirect | ||
| ) |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,316 @@ | ||||||||||||||||||||||||||||||||||||||||
| package main | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| import ( | ||||||||||||||||||||||||||||||||||||||||
| "fmt" | ||||||||||||||||||||||||||||||||||||||||
| "github.com/gin-gonic/gin" | ||||||||||||||||||||||||||||||||||||||||
| "gorm.io/driver/mysql" | ||||||||||||||||||||||||||||||||||||||||
| "gorm.io/gorm" | ||||||||||||||||||||||||||||||||||||||||
| "io" | ||||||||||||||||||||||||||||||||||||||||
| "net/http" | ||||||||||||||||||||||||||||||||||||||||
| "strconv" | ||||||||||||||||||||||||||||||||||||||||
| "time" | ||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| type User struct { | ||||||||||||||||||||||||||||||||||||||||
| ID int | ||||||||||||||||||||||||||||||||||||||||
| Name string | ||||||||||||||||||||||||||||||||||||||||
| Pass string | ||||||||||||||||||||||||||||||||||||||||
| Email string | ||||||||||||||||||||||||||||||||||||||||
| Identy int | ||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+17
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo in Struct Field: 'Identy' Should Be 'Identity' The field Apply this diff to correct the typo: type User struct {
ID int
Name string
Pass string
Email string
- Identy int
+ Identity int
}Ensure to update all occurrences of 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+14
to
+20
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Security Issue: Storing Passwords in Plain Text The To address this, you can modify the type User struct {
ID int
Name string
- Pass string
+ Pass []byte // Store hashed passwords
Email string
- Identy int
+ Identity int
}In your signup handler, hash the password before saving the user: // In the /signup POST handler
password := c.PostForm("password")
+hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
+if err != nil {
+ c.HTML(http.StatusInternalServerError, "signup.tmpl", gin.H{
+ "error": "Internal Server Error",
+ })
+ return
+}
// When creating the user
-userSign = User{Name: username, Pass: password, Email: email, Identy: identity}
+userSign = User{Name: username, Pass: hashedPassword, Email: email, Identity: identity}In your login handler, compare the hashed password: // In the /login POST handler
-password := c.PostForm("password")
+inputPassword := c.PostForm("password")
// After retrieving userLog from the database
-if password != userLog.Pass {
+if err := bcrypt.CompareHashAndPassword(userLog.Pass, []byte(inputPassword)); err != nil {
// Passwords do not match
}Don't forget to import the bcrypt package: import "golang.org/x/crypto/bcrypt" |
||||||||||||||||||||||||||||||||||||||||
| type Question struct { | ||||||||||||||||||||||||||||||||||||||||
| ID int | ||||||||||||||||||||||||||||||||||||||||
| Content string | ||||||||||||||||||||||||||||||||||||||||
| From string | ||||||||||||||||||||||||||||||||||||||||
| Time time.Time | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| var UserNow User | ||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Concurrency Issue: Global Variable Using the global variable Instead, implement session management to track user sessions securely. You can use a session middleware like import (
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
)
// In your main function, set up the session store
func main() {
r := gin.Default()
store := cookie.NewStore([]byte("secret"))
r.Use(sessions.Sessions("session", store))
// ...
}Then, in your handlers, manage the session data: // In login handler
session := sessions.Default(c)
session.Set("user_id", userLog.ID)
session.Save()// In logout handler
session := sessions.Default(c)
session.Clear()
session.Save() |
||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| func IsLog(c *gin.Context) { | ||||||||||||||||||||||||||||||||||||||||
| if UserNow.Name == "" { | ||||||||||||||||||||||||||||||||||||||||
| c.Redirect(http.StatusFound, "/") | ||||||||||||||||||||||||||||||||||||||||
| c.Abort() | ||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||
| c.Next() | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+37
to
+44
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Concurrency Issue: Global Variable Using a global variable Consider implementing session management to handle user authentication securely. You can use middleware like import (
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
)
// In your main function
store := cookie.NewStore([]byte("secret"))
r.Use(sessions.Sessions("session", store))Update your handlers to use sessions: // In login handler
-session := sessions.Default(c)
-session.Set("user_id", userLog.ID)
-session.Save()
+session := sessions.Default(c)
+session.Set("user_id", userLog.ID)
+session.Save()Modify the func IsLog(c *gin.Context) {
- if UserNow.Name == "" {
+ session := sessions.Default(c)
+ userID := session.Get("user_id")
+ if userID == nil {
c.Redirect(http.StatusFound, "/")
c.Abort()
} else {
+ // Retrieve user information if needed
c.Next()
}
} |
||||||||||||||||||||||||||||||||||||||||
| func main() { | ||||||||||||||||||||||||||||||||||||||||
| r := gin.Default() | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| dsn := "root:794ASMIN@soleca@tcp(127.0.0.1:3306)/my_database?charset=utf8mb4&parseTime=True&loc=Local" | ||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Security Issue: Hardcoded Database Credentials The database credentials are hardcoded in the You can modify the code to read from environment variables: -import (
+import (
"fmt"
"github.com/gin-gonic/gin"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"io"
"net/http"
"strconv"
"time"
+ "os"
)
func main() {
- dsn := "root:794ASMIN@soleca@tcp(127.0.0.1:3306)/my_database?charset=utf8mb4&parseTime=True&loc=Local"
+ dbUser := os.Getenv("DB_USER")
+ dbPassword := os.Getenv("DB_PASSWORD")
+ dbHost := os.Getenv("DB_HOST")
+ dbName := os.Getenv("DB_NAME")
+ dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
+ dbUser, dbPassword, dbHost, dbName)Ensure you set the environment variables
|
||||||||||||||||||||||||||||||||||||||||
| db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) | ||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||
| panic("connecting filed !!!") | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| db.AutoMigrate(&User{}, &Question{}) | ||||||||||||||||||||||||||||||||||||||||
| //重置自增主键 | ||||||||||||||||||||||||||||||||||||||||
| //db.Exec("ALTER TABLE users AUTO_INCREMENT = 1") | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| //查询某一个用户的方法 | ||||||||||||||||||||||||||||||||||||||||
| //a := db.Where("name = ? ", "SOLECA").First(&User{}) | ||||||||||||||||||||||||||||||||||||||||
| //if a.Error == gorm.ErrRecordNotFound { | ||||||||||||||||||||||||||||||||||||||||
| // u0 := User{Name: "SOLECA", Pass: "123123", Identy: 0} | ||||||||||||||||||||||||||||||||||||||||
| // db.Create(&u0) | ||||||||||||||||||||||||||||||||||||||||
| //} | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| r.LoadHTMLGlob("templates/*") | ||||||||||||||||||||||||||||||||||||||||
| r.GET("/", func(c *gin.Context) { | ||||||||||||||||||||||||||||||||||||||||
| UserNow.Name = "" | ||||||||||||||||||||||||||||||||||||||||
| c.HTML(http.StatusOK, "index.tmpl", nil) | ||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
| r.POST("/login", func(c *gin.Context) { | ||||||||||||||||||||||||||||||||||||||||
| username := c.PostForm("username") | ||||||||||||||||||||||||||||||||||||||||
| password := c.PostForm("password") | ||||||||||||||||||||||||||||||||||||||||
| var userLog User | ||||||||||||||||||||||||||||||||||||||||
| err := db.Where("name = ? ", username).First(&userLog).Error | ||||||||||||||||||||||||||||||||||||||||
| if err == gorm.ErrRecordNotFound { | ||||||||||||||||||||||||||||||||||||||||
| c.HTML(http.StatusOK, "index.tmpl", gin.H{ | ||||||||||||||||||||||||||||||||||||||||
| "message": "登录失败!你还没有注册", | ||||||||||||||||||||||||||||||||||||||||
| "message2": "没有用户?现在注册一个▼ ▼ ▼", | ||||||||||||||||||||||||||||||||||||||||
| "v": 0, | ||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||
| if password != userLog.Pass { | ||||||||||||||||||||||||||||||||||||||||
| c.HTML(http.StatusOK, "index.tmpl", gin.H{ | ||||||||||||||||||||||||||||||||||||||||
| "message": "您输入的密码不正确", | ||||||||||||||||||||||||||||||||||||||||
| "v": 1, | ||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||
| UserNow = userLog | ||||||||||||||||||||||||||||||||||||||||
| c.Redirect(http.StatusFound, "/home") | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+60
to
+84
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Security Issue: Plaintext Password Verification In the login handler, passwords are compared in plaintext, which is insecure and assumes passwords are stored in plaintext. After hashing passwords during signup, update the login handler to verify hashed passwords: // In the /login POST handler
-password := c.PostForm("password")
+inputPassword := c.PostForm("password")
// After retrieving userLog from the database
-if password != userLog.Pass {
+if err := bcrypt.CompareHashAndPassword(userLog.Pass, []byte(inputPassword)); err != nil {
c.HTML(http.StatusOK, "index.tmpl", gin.H{
"message": "Incorrect password",
"v": 1,
})
return
}
|
||||||||||||||||||||||||||||||||||||||||
| r.GET("/signup", func(c *gin.Context) { | ||||||||||||||||||||||||||||||||||||||||
| c.HTML(http.StatusOK, "signup.tmpl", gin.H{}) | ||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
| r.POST("/signup", func(c *gin.Context) { | ||||||||||||||||||||||||||||||||||||||||
| username := c.PostForm("username") | ||||||||||||||||||||||||||||||||||||||||
| password := c.PostForm("password") | ||||||||||||||||||||||||||||||||||||||||
| email := c.PostForm("email") | ||||||||||||||||||||||||||||||||||||||||
| submission := c.PostForm("submission") | ||||||||||||||||||||||||||||||||||||||||
| var userSign User | ||||||||||||||||||||||||||||||||||||||||
| err := db.Where("name = ? ", username).First(&userSign).Error | ||||||||||||||||||||||||||||||||||||||||
| if err == gorm.ErrRecordNotFound { | ||||||||||||||||||||||||||||||||||||||||
| if submission == "123321" { | ||||||||||||||||||||||||||||||||||||||||
| userSign = User{Name: username, Pass: password, Email: email, Identy: 0} | ||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+97
to
+98
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Security Issue: Hardcoded Admin Access Code The admin access code Consider implementing a secure method for admin registration, such as:
Update the code to reflect this change: - if submission == "123321" {
+ if isValidAdminSubmission(submission) {
// Admin registration logic
} else {
// Regular user registration
}Define the
|
||||||||||||||||||||||||||||||||||||||||
| db.Create(&userSign) | ||||||||||||||||||||||||||||||||||||||||
| //c.SetCookie("message", "管理员注册成功!", 3600, "/", "localhost", false, true) | ||||||||||||||||||||||||||||||||||||||||
| c.Redirect(http.StatusFound, "/") | ||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||
| userSign = User{Name: username, Pass: password, Email: email, Identy: 1} | ||||||||||||||||||||||||||||||||||||||||
| db.Create(&userSign) | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| c.Redirect(http.StatusFound, "/") | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||
| c.HTML(http.StatusOK, "signup.tmpl", gin.H{ | ||||||||||||||||||||||||||||||||||||||||
| "text": "用户名重复!请重试", | ||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
| r.GET("/reset", func(c *gin.Context) { | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| //---------------------------------------------------------------------------- | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| r.GET("/home", IsLog, func(c *gin.Context) { | ||||||||||||||||||||||||||||||||||||||||
| if UserNow.Name == "" { | ||||||||||||||||||||||||||||||||||||||||
| c.Redirect(http.StatusFound, "/") | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| v := UserNow.Identy | ||||||||||||||||||||||||||||||||||||||||
| var questions []Question | ||||||||||||||||||||||||||||||||||||||||
| err := db.Find(&questions).Error | ||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||
| fmt.Println("this") | ||||||||||||||||||||||||||||||||||||||||
| c.JSON(http.StatusBadRequest, gin.H{"error": "NO QUESTIONS"}) | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| c.HTML(http.StatusOK, "home.tmpl", gin.H{ | ||||||||||||||||||||||||||||||||||||||||
| "Name": UserNow.Name, | ||||||||||||||||||||||||||||||||||||||||
| "V": v, | ||||||||||||||||||||||||||||||||||||||||
| "K": 1, | ||||||||||||||||||||||||||||||||||||||||
| "questions": questions, | ||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
| home := r.Group("/home") | ||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||
| home.POST("/new", IsLog, func(c *gin.Context) { | ||||||||||||||||||||||||||||||||||||||||
| new1 := c.PostForm("new") | ||||||||||||||||||||||||||||||||||||||||
| var NewQuestion Question = Question{Content: new1, From: UserNow.Name, Time: time.Now()} | ||||||||||||||||||||||||||||||||||||||||
| err := db.Create(&NewQuestion).Error | ||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||
| c.JSON(http.StatusBadRequest, gin.H{"error": "failed"}) | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| c.Redirect(http.StatusFound, "/home/all") | ||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+168
to
+175
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Error Handling: Missing Error Response In the For consistency, consider providing user-friendly HTML responses for errors or redirecting appropriately. if err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": "failed"})
+ c.HTML(http.StatusInternalServerError, "error.tmpl", gin.H{
+ "message": "Failed to create a new question.",
+ })
return
}
c.Redirect(http.StatusFound, "/home/all")📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
| home.GET("/manage", IsLog, func(c *gin.Context) { | ||||||||||||||||||||||||||||||||||||||||
| if UserNow.Identy == 0 { | ||||||||||||||||||||||||||||||||||||||||
| fmt.Println("ok") | ||||||||||||||||||||||||||||||||||||||||
| v := UserNow.Identy | ||||||||||||||||||||||||||||||||||||||||
| var questionss []Question | ||||||||||||||||||||||||||||||||||||||||
| err := db.Find(&questionss).Error | ||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||
| fmt.Println("this") | ||||||||||||||||||||||||||||||||||||||||
| c.JSON(http.StatusBadRequest, gin.H{"error": "NO QUESTIONS"}) | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| c.HTML(http.StatusOK, "home.tmpl", gin.H{ | ||||||||||||||||||||||||||||||||||||||||
| "Name": UserNow.Name, | ||||||||||||||||||||||||||||||||||||||||
| "V": v, | ||||||||||||||||||||||||||||||||||||||||
| "K": 0, | ||||||||||||||||||||||||||||||||||||||||
| "questions": questionss, | ||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
| home.GET("/all", IsLog, func(c *gin.Context) { | ||||||||||||||||||||||||||||||||||||||||
| v := UserNow.Identy | ||||||||||||||||||||||||||||||||||||||||
| var questions []Question | ||||||||||||||||||||||||||||||||||||||||
| err := db.Find(&questions).Error | ||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||
| c.JSON(http.StatusBadRequest, gin.H{"error": "NO QUESTIONS"}) | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| c.HTML(http.StatusOK, "home.tmpl", gin.H{ | ||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+225
to
+229
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Handle Database Errors Appropriately The error handling for Adjust the error handling to catch actual database errors: err := db.Find(&questions).Error
if err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": "NO QUESTIONS"})
+ c.HTML(http.StatusInternalServerError, "error.tmpl", gin.H{
+ "message": "Database error occurred.",
+ })
+ return
}
+// Optionally, handle the case where 'questions' is empty in your template
|
||||||||||||||||||||||||||||||||||||||||
| "Name": UserNow.Name, | ||||||||||||||||||||||||||||||||||||||||
| "V": v, | ||||||||||||||||||||||||||||||||||||||||
| "K": 1, | ||||||||||||||||||||||||||||||||||||||||
| "questions": questions, | ||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
| home.GET("/my", IsLog, func(c *gin.Context) { | ||||||||||||||||||||||||||||||||||||||||
| var questions []Question | ||||||||||||||||||||||||||||||||||||||||
| db.Where("`from` = ?", UserNow.Name).Find(&questions) | ||||||||||||||||||||||||||||||||||||||||
| //if err != nil { | ||||||||||||||||||||||||||||||||||||||||
| // c.JSON(http.StatusBadRequest, gin.H{"error": "NO QUESTIONS"}) | ||||||||||||||||||||||||||||||||||||||||
| //} | ||||||||||||||||||||||||||||||||||||||||
| c.HTML(http.StatusOK, "showmy.tmpl", gin.H{ | ||||||||||||||||||||||||||||||||||||||||
| "questions": questions, | ||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+238
to
+246
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Error Handling: Commented-Out Error Check In the Uncomment and update the error handling logic: db.Where("`from` = ?", UserNow.Name).Find(&questions)
-if err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": "NO QUESTIONS"})
-}
+if err := db.Where("`from` = ?", UserNow.Name).Find(&questions).Error; err != nil {
+ c.HTML(http.StatusInternalServerError, "error.tmpl", gin.H{
+ "message": "Failed to retrieve your questions.",
+ })
+ return
+}
|
||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
| home.POST("home/:id/answer", IsLog, func(c *gin.Context) { | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
| home.DELETE("/delete", IsLog, func(c *gin.Context) { | ||||||||||||||||||||||||||||||||||||||||
| body, _ := io.ReadAll(c.Request.Body) | ||||||||||||||||||||||||||||||||||||||||
| // 将字符串转换为数值 | ||||||||||||||||||||||||||||||||||||||||
| receive, _ := strconv.Atoi(string(body)) | ||||||||||||||||||||||||||||||||||||||||
| db.Where("id = ?", receive).Delete(&Question{}) | ||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+307
to
+311
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Security Issue: Reading Request Body Directly Directly reading the request body using Modify the handler to parse form data or URL parameters: -home.DELETE("/question/delete", IsLog, func(c *gin.Context) {
- body, _ := io.ReadAll(c.Request.Body)
- receive, _ := strconv.Atoi(string(body))
+home.POST("/question/delete", IsLog, func(c *gin.Context) {
+ id := c.PostForm("id")
+ receive, err := strconv.Atoi(id)
+ if err != nil {
+ c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{
+ "message": "Invalid question ID.",
+ })
+ return
+ }
db.Where("id = ?", receive).Delete(&Question{})
})📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| r.Run(":8080") | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| /* | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| c.Request.URL.Path="/b" | ||||||||||||||||||||||||||||||||||||||||
| r.HandleContext(c) | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| //cookie重定向 | ||||||||||||||||||||||||||||||||||||||||
| c.SetCookie("message", "注册成功!", 3600, "/", "", false, true) | ||||||||||||||||||||||||||||||||||||||||
| c.Redirect(http.StatusFound, "/") | ||||||||||||||||||||||||||||||||||||||||
| router.GET("/", func(c *gin.Context) { | ||||||||||||||||||||||||||||||||||||||||
| // 获取 cookie 中的消息 | ||||||||||||||||||||||||||||||||||||||||
| message, err := c.Cookie("message") | ||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||
| message = "" | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| c.HTML(http.StatusOK, "hello.tmpl", gin.H{ | ||||||||||||||||||||||||||||||||||||||||
| "message1": message, | ||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| package controllers | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| import ( | ||||||||||||||||||||||||||||||||||||||||
| "net/http" | ||||||||||||||||||||||||||||||||||||||||
| "github.com/gin-gonic/gin" | ||||||||||||||||||||||||||||||||||||||||
| "gorm.io/gorm" | ||||||||||||||||||||||||||||||||||||||||
| "myapp/models" | ||||||||||||||||||||||||||||||||||||||||
| "golang.org/x/crypto/bcrypt" | ||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| var db *gorm.DB | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| func init() { | ||||||||||||||||||||||||||||||||||||||||
| var err error | ||||||||||||||||||||||||||||||||||||||||
| db, err = gorm.Open(sqlite.Open("test.db"), &gorm.Config{}) | ||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||
| panic("failed to connect database") | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| func ShowLoginPage(c *gin.Context) { | ||||||||||||||||||||||||||||||||||||||||
| c.HTML(http.StatusOK, "login.html", gin.H{ | ||||||||||||||||||||||||||||||||||||||||
| "title": "Login", | ||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| func PerformLogin(c *gin.Context) { | ||||||||||||||||||||||||||||||||||||||||
| var user models.User | ||||||||||||||||||||||||||||||||||||||||
| username := c.PostForm("username") | ||||||||||||||||||||||||||||||||||||||||
| password := c.PostForm("password") | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| if err := db.Where("username = ?", username).First(&user).Error; err != nil { | ||||||||||||||||||||||||||||||||||||||||
| c.HTML(http.StatusUnauthorized, "login.html", gin.H{ | ||||||||||||||||||||||||||||||||||||||||
| "ErrorTitle": "Login Failed", | ||||||||||||||||||||||||||||||||||||||||
| "ErrorMessage": "Invalid credentials provided", | ||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil { | ||||||||||||||||||||||||||||||||||||||||
| c.HTML(http.StatusUnauthorized, "login.html", gin.H{ | ||||||||||||||||||||||||||||||||||||||||
| "ErrorTitle": "Login Failed", | ||||||||||||||||||||||||||||||||||||||||
| "ErrorMessage": "Invalid credentials provided", | ||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| c.HTML(http.StatusOK, "login.html", gin.H{ | ||||||||||||||||||||||||||||||||||||||||
| "title": "Login Successful", | ||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| <!DOCTYPE html> | ||||||||||||||||||||||||||||||||||||||||
| <html lang="en"> | ||||||||||||||||||||||||||||||||||||||||
| <head> | ||||||||||||||||||||||||||||||||||||||||
| <meta charset="UTF-8"> | ||||||||||||||||||||||||||||||||||||||||
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||||||||||||||||||||||||||||||||||||||
| <title>{{ .title }}</title> | ||||||||||||||||||||||||||||||||||||||||
| </head> | ||||||||||||||||||||||||||||||||||||||||
| <body> | ||||||||||||||||||||||||||||||||||||||||
| <h1>{{ .title }}</h1> | ||||||||||||||||||||||||||||||||||||||||
| {{ if .ErrorTitle }} | ||||||||||||||||||||||||||||||||||||||||
| <h2>{{ .ErrorTitle }}</h2> | ||||||||||||||||||||||||||||||||||||||||
| <p>{{ .ErrorMessage }}</p> | ||||||||||||||||||||||||||||||||||||||||
| {{ end }} | ||||||||||||||||||||||||||||||||||||||||
| <form action="/login" method="post"> | ||||||||||||||||||||||||||||||||||||||||
| <label for="username">Username:</label> | ||||||||||||||||||||||||||||||||||||||||
| <input type="text" id="username" name="username" required> | ||||||||||||||||||||||||||||||||||||||||
| <br> | ||||||||||||||||||||||||||||||||||||||||
| <label for="password">Password:</label> | ||||||||||||||||||||||||||||||||||||||||
| <input type="password" id="password" name="password" required> | ||||||||||||||||||||||||||||||||||||||||
| <br> | ||||||||||||||||||||||||||||||||||||||||
| <button type="submit">Login</button> | ||||||||||||||||||||||||||||||||||||||||
| </form> | ||||||||||||||||||||||||||||||||||||||||
| </body> | ||||||||||||||||||||||||||||||||||||||||
| </html> | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Security Issue: Storing Passwords in Plain Text
The
Passfield in theUserstruct stores passwords as plain text, which poses a significant security risk. Passwords should be hashed using a strong hashing algorithm like bcrypt before being stored.Apply this diff to hash passwords:
type User struct { ID int Name string - Pass string + Pass []byte // Store hashed passwords Email string Identy int }In your signup and reset handlers, hash the password before saving:
In your login handler, compare hashed passwords: