-
Notifications
You must be signed in to change notification settings - Fork 26
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
feat:finish task #5
base: main
Are you sure you want to change the base?
Changes from all commits
99b8020
c91fe33
dda1592
6118c28
2be5f6b
c34a07d
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,88 @@ | ||
问答平台(后端) | ||
|
||
1.概述 | ||
|
||
该后端程序实现注册登入,问题和回答的上传删除显示。 | ||
|
||
*** | ||
|
||
2.API | ||
|
||
(1)“/v1/register”(注册) | ||
|
||
name:用户名称 | ||
|
||
telephone:用户电话 | ||
|
||
password:密码 | ||
|
||
(2)“/v1/login”(登入) | ||
|
||
telephone:用户电话 | ||
|
||
password:用户密码 | ||
|
||
(3)“/problem_hall/put”(输入问题) | ||
|
||
title:问题标题 | ||
|
||
description:问题描述 | ||
|
||
name:提问者账号名 | ||
|
||
key:密匙(删除问题用密匙) | ||
|
||
——问题名不可重复 | ||
|
||
(4)“/problem_hall/delete”(删除问题) | ||
|
||
title:问题标题 | ||
|
||
key:密匙(密匙正确可删除) | ||
|
||
(5)“/problem_hall/hall”(读取数据发送给前端) | ||
|
||
first:开始跳过的数据 | ||
|
||
number:读取的数据数 | ||
(6)"/problem_hall/research"(给题目读问题) | ||
title:问题题目 | ||
|
||
(6)“/answer/put”(提供回答) | ||
|
||
description:回答内容 | ||
|
||
key:密匙(删除回答) | ||
|
||
name:回答者账号名 | ||
|
||
title:回答对应的问题标题 | ||
|
||
(7)“/answer/delete”(删除问题) | ||
|
||
text:问题内容 | ||
|
||
title:回答对应的问题标题 | ||
|
||
key;密匙 | ||
|
||
name:回答者的名字 | ||
|
||
(8)“/answer/hall”(显示回答数据) | ||
|
||
title:问题标题 | ||
|
||
first:开始跳过的数据 | ||
|
||
number:读取的数据量 | ||
(9)检验登入状态 | ||
在操作问题和回答时会检验是否登入 | ||
(10)登出 | ||
name:在输入用户名 | ||
|
||
*** | ||
apifox链接:https://qsefuqgces.apifox.cn/ | ||
*** | ||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package account | ||
|
||
import "gorm.io/gorm" | ||
|
||
type User struct { //用户 | ||
gorm.Model `json:"gorm_._model"` | ||
Name string `json:"name,omitempty"` | ||
Telephone string `json:"telephone,omitempty"` | ||
Password string `json:"password,omitempty"` | ||
ID int `json:"id,omitempty"` | ||
} | ||
type session struct { | ||
Name string | ||
Value string | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package account | ||
|
||
import ( | ||
"github.com/gin-gonic/gin" | ||
"golang.org/x/crypto/bcrypt" | ||
"strconv" | ||
"wonder-world/db" | ||
"wonder-world/tool" | ||
) | ||
|
||
func Login(c *gin.Context) { | ||
db := db.Dbfrom() | ||
telephone := c.PostForm("telephone") | ||
password := c.PostForm("password") | ||
var user User | ||
db.Where("telephone = ?", telephone).First(&user) | ||
if user.ID == 0 { | ||
c.JSON(422, gin.H{ | ||
"code": 422, | ||
"message": "用户不存在", | ||
}) | ||
return | ||
} | ||
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil { | ||
c.JSON(422, gin.H{ | ||
"code": 422, | ||
"message": "密码错误", | ||
}) | ||
return | ||
} | ||
f := 1 | ||
for f == 1 { | ||
name := tool.Randam() | ||
value := tool.Randam() | ||
_, err := c.Cookie(strconv.Itoa(name)) | ||
if err != nil { | ||
f = -1 | ||
c.SetCookie(user.Name, strconv.Itoa(value), 3600, "/", "http://127.0.0.1:8080", false, false) | ||
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. Avoid using Using Incorrect domain format in The Suggested change: - c.SetCookie(user.Name, strconv.Itoa(value), 3600, "/", "http://127.0.0.1:8080", false, false)
+ c.SetCookie("session_token", token, 3600, "/", "127.0.0.1", false, true)
|
||
newsession := session{ | ||
Name: strconv.Itoa(name), | ||
Value: strconv.Itoa(value), | ||
} | ||
Comment on lines
+39
to
+42
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. Ensure the The Define the struct as: type Session struct {
ID uint
UserID uint
Token string
} |
||
db.Create(&newsession) | ||
c.JSON(200, gin.H{ | ||
"code": 200, | ||
"message": "success", | ||
}) | ||
return | ||
} | ||
} | ||
Comment on lines
+33
to
+50
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. 🛠️ Refactor suggestion Inefficient and insecure session management implementation The current approach generates random cookie names and values in a loop until a unique one is found, which is inefficient and may introduce security vulnerabilities. Additionally, using random integers for cookie names and values without sufficient randomness or entropy can be insecure. It's recommended to use standardized session management practices. Consider using a secure, standard method for session management:
Suggested refactor: import (
// Add these imports
"crypto/rand"
"encoding/hex"
)
// Helper function to generate a secure random token
func generateSessionToken() (string, error) {
byteToken := make([]byte, 32)
if _, err := rand.Read(byteToken); err != nil {
return "", err
}
return hex.EncodeToString(byteToken), nil
}
// Inside the Login function
token, err := generateSessionToken()
if err != nil {
c.JSON(500, gin.H{
"code": 500,
"message": "服务器错误",
})
return
}
// Set the cookie with a constant name
c.SetCookie("session_token", token, 3600, "/", "127.0.0.1", false, true)
// Ensure that the Session struct is properly defined
newSession := Session{
UserID: user.ID,
Token: token,
}
db.Create(&newSession)
c.JSON(200, gin.H{
"code": 200,
"message": "登录成功",
})
return Make sure the type Session struct {
ID uint
UserID uint
Token string
} |
||
|
||
c.JSON(422, gin.H{ | ||
"code": 422, | ||
"message": "cookie failure", | ||
}) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package account | ||
|
||
import ( | ||
"github.com/gin-gonic/gin" | ||
"golang.org/x/crypto/bcrypt" | ||
"net/http" | ||
"wonder-world/db" | ||
) | ||
|
||
func Register(c *gin.Context) { | ||
db := db.Dbfrom() | ||
var u User | ||
u.Name = c.PostForm("name") | ||
u.Password = c.PostForm("password") | ||
u.Telephone = c.PostForm("telephone") | ||
Comment on lines
+10
to
+15
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. 🛠️ Refactor suggestion Consider adding input sanitization. While the function correctly retrieves user input, it's advisable to sanitize the input to prevent potential security issues like SQL injection or XSS attacks. Consider using a library like import "github.com/microcosm-cc/bluemonday"
// At the beginning of the Register function
p := bluemonday.UGCPolicy()
u.Name = p.Sanitize(c.PostForm("name"))
u.Password = p.Sanitize(c.PostForm("password"))
u.Telephone = p.Sanitize(c.PostForm("telephone")) |
||
if len(u.Name) == 0 { | ||
c.JSON(422, gin.H{ | ||
"code": 422, | ||
"message": "用户名不能为空", | ||
}) | ||
return | ||
} | ||
if len(u.Telephone) != 11 { | ||
c.JSON(422, gin.H{ | ||
"code": 422, | ||
"message": "手机号必须为11位", | ||
}) | ||
return | ||
} | ||
if len(u.Password) <= 6 { | ||
c.JSON(422, gin.H{ | ||
"code": 422, | ||
"message": "密码不能少于6位", | ||
}) | ||
return | ||
} | ||
Comment on lines
+16
to
+36
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. 🛠️ Refactor suggestion Enhance input validation and error handling. While the current validations cover basic requirements, there are several areas for improvement:
Here's an example of how you could improve the validation: import (
"regexp"
"net/http"
)
const (
StatusUnprocessableEntity = 422
)
func isValidPhoneNumber(phone string) bool {
pattern := `^1[3-9]\d{9}$`
match, _ := regexp.MatchString(pattern, phone)
return match
}
func isStrongPassword(password string) bool {
return len(password) >= 8 &&
regexp.MustCompile(`[A-Z]`).MatchString(password) &&
regexp.MustCompile(`[a-z]`).MatchString(password) &&
regexp.MustCompile(`[0-9]`).MatchString(password) &&
regexp.MustCompile(`[!@#$%^&*]`).MatchString(password)
}
// In the Register function
if !isValidPhoneNumber(u.Telephone) {
c.JSON(http.StatusUnprocessableEntity, gin.H{
"code": StatusUnprocessableEntity,
"message": "Invalid phone number format",
})
return
}
if !isStrongPassword(u.Password) {
c.JSON(http.StatusUnprocessableEntity, gin.H{
"code": StatusUnprocessableEntity,
"message": "Password must be at least 8 characters long and include uppercase, lowercase, number, and special character",
})
return
} |
||
var user User | ||
db.Where("telephone = ?", u.Telephone).First(&user) | ||
if user.ID != 0 { | ||
c.JSON(422, gin.H{ | ||
"code": 422, | ||
"message": "用户已存在", | ||
}) | ||
return | ||
} | ||
Comment on lines
+37
to
+45
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. 🛠️ Refactor suggestion Consider separating database operations from the handler. While the existing user check is functional, it's generally a good practice to separate concerns by moving database operations to a separate layer (e.g., a repository pattern). Consider creating a separate package for database operations. Here's an example of how you could refactor this: // In a new file, e.g., repository/user_repository.go
package repository
import "gorm.io/gorm"
type UserRepository struct {
DB *gorm.DB
}
func (r *UserRepository) FindByTelephone(telephone string) (*User, error) {
var user User
result := r.DB.Where("telephone = ?", telephone).First(&user)
if result.Error != nil {
if result.Error == gorm.ErrRecordNotFound {
return nil, nil
}
return nil, result.Error
}
return &user, nil
}
// In the Register function
userRepo := repository.UserRepository{DB: db}
existingUser, err := userRepo.FindByTelephone(u.Telephone)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"code": http.StatusInternalServerError,
"message": "Error checking existing user",
})
return
}
if existingUser != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{
"code": http.StatusUnprocessableEntity,
"message": "User already exists",
})
return
} This approach improves testability and maintainability of your code. |
||
hasedPassword, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost) | ||
if err != nil { | ||
c.JSON(http.StatusUnprocessableEntity, gin.H{ | ||
"code": 500, | ||
"message": "密码加密错误", | ||
}) | ||
return | ||
} | ||
u.Password = string(hasedPassword) | ||
db.Create(&u) | ||
c.JSON(200, gin.H{ | ||
"code": 200, | ||
"message": "success", | ||
}) | ||
|
||
Comment on lines
+46
to
+60
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. 🛠️ Refactor suggestion Improve error handling and success response for user creation. The password hashing and user creation process is generally well-implemented, but there are a few areas for improvement:
Consider the following improvements: hashedPassword, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"code": http.StatusInternalServerError,
"message": "Error hashing password",
})
return
}
u.Password = string(hashedPassword)
result := db.Create(&u)
if result.Error != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"code": http.StatusInternalServerError,
"message": "Error creating user",
})
return
}
c.JSON(http.StatusCreated, gin.H{
"code": http.StatusCreated,
"message": "User created successfully",
"data": gin.H{
"id": u.ID,
"name": u.Name,
"telephone": u.Telephone,
},
}) This implementation adds error handling for the user creation process and provides more information in the success response, while still maintaining security by not returning sensitive information like the password. |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package answer | ||
|
||
import ( | ||
"fmt" | ||
"github.com/gin-gonic/gin" | ||
db2 "wonder-world/db" | ||
"wonder-world/test" | ||
) | ||
|
||
func Andelet(c *gin.Context) { | ||
db := db2.Dbfrom() | ||
f := 1 | ||
key := c.PostForm("key") | ||
title := c.PostForm("title") | ||
text := c.PostForm("text") | ||
name := c.PostForm("name") | ||
var user Ques | ||
db.Where("title = ?", title).First(&user) | ||
if user.ID == 0 { | ||
c.JSON(422, gin.H{ | ||
"code": 422, | ||
"message": "问题不存在", | ||
}) | ||
return | ||
} | ||
Comment on lines
+17
to
+25
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. Improve error handling and consider defining structs.
Here's a suggested improvement: +type Ques struct {
+ ID uint
+ Title string
+ // Add other necessary fields
+}
var user Ques
db.Where("title = ?", title).First(&user)
if user.ID == 0 {
- c.JSON(422, gin.H{
- "code": 422,
+ c.JSON(404, gin.H{
+ "code": 404,
"message": "问题不存在",
})
return
}
|
||
if !test.Getcookie(c, name) { | ||
c.JSON(422, gin.H{ | ||
"code": 422, | ||
"message": "重登", | ||
}) | ||
return | ||
} | ||
var use []Anse | ||
db.Where("name = ?", name).Find(&use) | ||
fmt.Println(use) | ||
if user.ID != 0 { | ||
for _, answer := range use { | ||
if answer.Text == text { | ||
if answer.Key == key { | ||
f = 0 | ||
db.Delete(&answer) | ||
break | ||
} | ||
} | ||
} | ||
if f == 1 { | ||
c.JSON(422, gin.H{ | ||
"code": 422, | ||
"message": "错误", | ||
}) | ||
return | ||
} | ||
c.JSON(200, gin.H{ | ||
"code": 200, | ||
"message": "success", | ||
}) | ||
} | ||
} | ||
Comment on lines
+36
to
+58
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. 🛠️ Refactor suggestion Refactor answer deletion logic for better readability and error handling.
Here's a suggested refactoring: - if user.ID != 0 {
- for _, answer := range use {
- if answer.Text == text {
- if answer.Key == key {
- f = 0
- db.Delete(&answer)
- break
- }
- }
- }
- if f == 1 {
- c.JSON(422, gin.H{
- "code": 422,
- "message": "错误",
- })
- return
- }
- c.JSON(200, gin.H{
- "code": 200,
- "message": "success",
- })
- }
+ tx := db.Begin()
+ defer func() {
+ if r := recover(); r != nil {
+ tx.Rollback()
+ }
+ }()
+
+ var answerToDelete Anse
+ if err := tx.Where("name = ? AND text = ? AND key = ?", name, text, key).First(&answerToDelete).Error; err != nil {
+ tx.Rollback()
+ c.JSON(404, gin.H{
+ "code": 404,
+ "message": "Answer not found",
+ })
+ return
+ }
+
+ if err := tx.Delete(&answerToDelete).Error; err != nil {
+ tx.Rollback()
+ c.JSON(500, gin.H{
+ "code": 500,
+ "message": "Failed to delete answer",
+ })
+ return
+ }
+
+ tx.Commit()
+ c.JSON(200, gin.H{
+ "code": 200,
+ "message": "Answer deleted successfully",
+ }) This refactoring improves error handling, uses a database transaction, and provides more descriptive error messages.
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package answer | ||
|
||
import ( | ||
"github.com/gin-gonic/gin" | ||
"strconv" | ||
db2 "wonder-world/db" | ||
) | ||
|
||
func Anhall(c *gin.Context) { | ||
db := db2.Dbfrom() | ||
Comment on lines
+9
to
+10
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. Add error handling for database connection. The Example implementation: db, err := db2.Dbfrom()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Database connection failed"})
return
} |
||
number := c.PostForm("first") | ||
number1 := c.PostForm("number") | ||
title := c.PostForm("title") | ||
var num, _ = strconv.Atoi(number) | ||
num1, _ := strconv.Atoi(number1) | ||
Comment on lines
+11
to
+15
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. Improve error handling and add input validation.
Consider implementing the following improvements:
num, err := strconv.Atoi(number)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid 'first' parameter"})
return
}
num1, err := strconv.Atoi(number1)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid 'number' parameter"})
return
}
if number == "" || number1 == "" || title == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "Missing required parameters"})
return
} |
||
var user []Anse | ||
db.Limit(num1).Offset(num).Find(&user) | ||
for _, answer := range user { | ||
if answer.Title == title { | ||
} | ||
c.JSON(200, gin.H{ | ||
"name": answer.Name, | ||
"text": answer.Text, | ||
}) | ||
} | ||
Comment on lines
+16
to
+25
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. Fix database query error handling and result processing logic. There are several issues in this section:
Consider implementing the following improvements:
result := db.Limit(num1).Offset(num).Find(&user)
if result.Error != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Database query failed"})
return
}
for _, answer := range user {
if answer.Title == title {
c.JSON(200, gin.H{
"name": answer.Name,
"text": answer.Text,
})
return // Return after finding the first match
}
}
// If no match is found
c.JSON(404, gin.H{"error": "No matching answer found"}) This will ensure that only matching answers are returned and that the function stops after finding the first match. |
||
} | ||
Comment on lines
+9
to
+26
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. 🛠️ Refactor suggestion Consider refactoring for improved robustness and functionality. The current implementation of
To make this function more robust and suitable for a Q&A platform API, consider the following suggestions:
Would you like assistance in refactoring this function to address these issues? I can provide a more detailed implementation that incorporates these improvements. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package answer | ||
|
||
import ( | ||
"github.com/gin-gonic/gin" | ||
db2 "wonder-world/db" | ||
"wonder-world/test" | ||
) | ||
|
||
func Anput(c *gin.Context) { | ||
db := db2.Dbfrom() | ||
description := c.PostForm("description") | ||
name := c.PostForm("name") | ||
key := c.PostForm("key") | ||
title := c.PostForm("title") | ||
Comment on lines
+9
to
+14
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. 🛠️ Refactor suggestion Consider using Gin's binding feature for form data. Instead of retrieving form fields individually, consider using Gin's binding feature. This approach is less error-prone and provides automatic validation. Here's an example of how you could refactor this: type AnswerInput struct {
Description string `form:"description" binding:"required"`
Name string `form:"name" binding:"required"`
Key string `form:"key" binding:"required"`
Title string `form:"title" binding:"required"`
}
func Anput(c *gin.Context) {
var input AnswerInput
if err := c.ShouldBind(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// Use input.Description, input.Name, etc.
// ...
} |
||
var user User | ||
db.Where("name = ?", name).First(&user) | ||
if user.ID == 0 { | ||
c.JSON(422, gin.H{ | ||
"code": 422, | ||
"message": "请输入正确的用户名", | ||
}) | ||
return | ||
} | ||
if !test.Getcookie(c, name) { | ||
c.JSON(422, gin.H{ | ||
"code": 422, | ||
"message": "重登", | ||
}) | ||
return | ||
} | ||
Comment on lines
+15
to
+30
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. 🛠️ Refactor suggestion Optimize user validation and consider internationalizing error messages.
if !test.Getcookie(c, name) {
c.JSON(http.StatusUnauthorized, gin.H{
"code": http.StatusUnauthorized,
"message": "Authentication required",
})
return
}
var user User
if err := db.Where("name = ?", name).First(&user).Error; err != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{
"code": http.StatusUnprocessableEntity,
"message": "Invalid username",
})
return
}
Would you like assistance in implementing these suggestions? |
||
var use Ques | ||
db.Where("title = ?", title).First(&use) | ||
if use.ID == 0 { | ||
c.JSON(422, gin.H{ | ||
"code": 422, | ||
"message": "问题不存在", | ||
}) | ||
return | ||
} | ||
newAnswer := Anse{ | ||
Name: name, | ||
Text: description, | ||
Key: key, | ||
Title: title, | ||
} | ||
db.Create(&newAnswer) | ||
Comment on lines
+31
to
+46
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. Improve error handling and struct definition.
var question Ques
if err := db.Where("title = ?", title).First(&question).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
c.JSON(http.StatusNotFound, gin.H{
"code": http.StatusNotFound,
"message": "Question not found",
})
} else {
c.JSON(http.StatusInternalServerError, gin.H{
"code": http.StatusInternalServerError,
"message": "Database error",
})
}
return
}
Please provide the definition for the |
||
c.JSON(200, gin.H{ | ||
"code": 200, | ||
"message": "success", | ||
}) | ||
|
||
Comment on lines
+47
to
+51
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. 🛠️ Refactor suggestion Enhance the response with more information and use HTTP status constants. Consider providing more information in the success response and use HTTP status constants for better readability: c.JSON(http.StatusOK, gin.H{
"code": http.StatusOK,
"message": "Answer created successfully",
"data": gin.H{
"id": newAnswer.ID,
"title": newAnswer.Title,
},
}) This provides more context about the created answer and uses the |
||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,25 @@ | ||||||||||||||||||||||||||||||
package answer | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
import "gorm.io/gorm" | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
type User struct { //用户 | ||||||||||||||||||||||||||||||
gorm.Model `json:"gorm_._model"` | ||||||||||||||||||||||||||||||
Name string `json:"name,omitempty"` | ||||||||||||||||||||||||||||||
Telephone string `json:"telephone,omitempty"` | ||||||||||||||||||||||||||||||
Password string `json:"password,omitempty"` | ||||||||||||||||||||||||||||||
ID int `json:"id,omitempty"` | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
Comment on lines
+5
to
+11
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 and design improvements needed in User struct
Consider applying these changes: type User struct { //用户
gorm.Model `json:"gorm_._model"`
Name string `json:"name,omitempty"`
Telephone string `json:"telephone,omitempty"`
- Password string `json:"password,omitempty"`
+ Password string `json:"-"` // Never expose password in JSON
- ID int `json:"id,omitempty"`
} Also, ensure that passwords are hashed before storage. Consider using a package like 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||
type Ques struct { //问题 | ||||||||||||||||||||||||||||||
gorm.Model | ||||||||||||||||||||||||||||||
Name string | ||||||||||||||||||||||||||||||
Title string | ||||||||||||||||||||||||||||||
Put string | ||||||||||||||||||||||||||||||
Key string | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
Comment on lines
+12
to
+18
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. Improve struct naming and field definitions
Consider applying these changes: -type Ques struct { //问题
+type Question struct { //问题
gorm.Model
- Name string
- Title string
- Put string
- Key string
+ Name string `json:"name"`
+ Title string `json:"title"`
+ Put string `json:"put"` // Consider renaming this field or adding a comment to explain its purpose
+ Key string `json:"key"`
} 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||
type Anse struct { //我、回答 | ||||||||||||||||||||||||||||||
Name string `json:"name"` | ||||||||||||||||||||||||||||||
Text string `json:"text"` | ||||||||||||||||||||||||||||||
Key string `json:"key"` | ||||||||||||||||||||||||||||||
Title string `json:"title"` | ||||||||||||||||||||||||||||||
gorm.Model | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
Comment on lines
+19
to
+25
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. Clarify struct purpose and improve naming
Consider applying these changes: -type Anse struct { //我、回答
+type Answer struct { //回答
+ gorm.Model
Name string `json:"name"`
Text string `json:"text"`
Key string `json:"key"`
Title string `json:"title"`
- gorm.Model
} Also, consider if you need a separate struct for "me" (user) or if this information can be included in the existing 📝 Committable suggestion
Suggested change
|
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.
Handle potential bcrypt errors properly
When
bcrypt.CompareHashAndPassword
returns an error, it might not always be due to an incorrect password (e.g., hash corruption). Currently, all errors are treated as "密码错误" (incorrect password). Consider distinguishing between authentication errors and other possible errors to enhance error handling.Suggested change: