update
This commit is contained in:
parent
2ab9f4ebd5
commit
5c2d928e40
1
.history/README_20240925151839.md
Normal file
1
.history/README_20240925151839.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
123
|
||||||
31
.history/README_20240925162207.md
Normal file
31
.history/README_20240925162207.md
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# TestFB
|
||||||
|
> 使用Go语言,实现用户登录、获取用户信息、修改用户信息。
|
||||||
|
|
||||||
|
## 工程要求:结构化工程,更加规范的代码编写。
|
||||||
|
## 工程使用的模块或技术:
|
||||||
|
1. Go语言
|
||||||
|
2. fiber框架
|
||||||
|
3. Gorm ORM框架
|
||||||
|
4. fiber下的storage/redis v3模块
|
||||||
|
5. JWT身份验证,存储在redis中
|
||||||
|
6. mysql,使用fiber下的storage/mysql v2模块
|
||||||
|
7. 日志,使用fiber自带的日志模块
|
||||||
|
|
||||||
|
## mysql模块
|
||||||
|
1. 数据库地址:localhost:3306
|
||||||
|
2. 数据库名称:testfb
|
||||||
|
3. 表名称:users
|
||||||
|
4. 字段:id, username, password, email, phone, created_at, updated_at
|
||||||
|
5. 密码字段需加密。
|
||||||
|
## redis模块
|
||||||
|
1. 存储用户的token信息
|
||||||
|
2. redis地址:localhost:6379
|
||||||
|
|
||||||
|
## 路由信息
|
||||||
|
1. 登录:POST /login
|
||||||
|
2. 获取当前用户信息: GET /user
|
||||||
|
3. 修改当前用户信息: PUT /user
|
||||||
|
4. 获取某个用户信息: GET /users/:id
|
||||||
|
|
||||||
|
## 其他
|
||||||
|
1. 日志保存在当前main.go目录下
|
||||||
56
.history/handlers/handlers_20240925161943.go
Normal file
56
.history/handlers/handlers_20240925161943.go
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"github.com/gofiber/storage/redis/v3"
|
||||||
|
"github.com/golang-jwt/jwt/v4"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
|
||||||
|
"testfb/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Login(db *gorm.DB, redisClient *redis.Storage) fiber.Handler {
|
||||||
|
return func(c *fiber.Ctx) error {
|
||||||
|
var input struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.BodyParser(&input); err != nil {
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid input"})
|
||||||
|
}
|
||||||
|
|
||||||
|
var user models.User
|
||||||
|
if err := db.Where("username = ?", input.Username).First(&user).Error; err != nil {
|
||||||
|
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Invalid credentials"})
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := user.ComparePassword(input.Password); err != nil {
|
||||||
|
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Invalid credentials"})
|
||||||
|
}
|
||||||
|
|
||||||
|
token := jwt.New(jwt.SigningMethodHS256)
|
||||||
|
claims := token.Claims.(jwt.MapClaims)
|
||||||
|
claims["user_id"] = user.ID
|
||||||
|
claims["exp"] = time.Now().Add(time.Hour * 24).Unix()
|
||||||
|
|
||||||
|
t, err := token.SignedString([]byte("your-secret-key"))
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Could not login"})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert user.ID to string before storing in Redis
|
||||||
|
userIDStr := strconv.FormatUint(uint64(user.ID), 10)
|
||||||
|
err = redisClient.Set(t, []byte(userIDStr), 24*time.Hour)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Could not store token"})
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(fiber.Map{"token": t})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... (rest of the file remains unchanged)
|
||||||
105
.history/handlers/handlers_20240925162137.go
Normal file
105
.history/handlers/handlers_20240925162137.go
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"github.com/gofiber/storage/redis/v3"
|
||||||
|
"github.com/golang-jwt/jwt/v4"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
|
||||||
|
"testfb/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Login(db *gorm.DB, redisClient *redis.Storage) fiber.Handler {
|
||||||
|
return func(c *fiber.Ctx) error {
|
||||||
|
var input struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.BodyParser(&input); err != nil {
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid input"})
|
||||||
|
}
|
||||||
|
|
||||||
|
var user models.User
|
||||||
|
if err := db.Where("username = ?", input.Username).First(&user).Error; err != nil {
|
||||||
|
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Invalid credentials"})
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := user.ComparePassword(input.Password); err != nil {
|
||||||
|
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Invalid credentials"})
|
||||||
|
}
|
||||||
|
|
||||||
|
token := jwt.New(jwt.SigningMethodHS256)
|
||||||
|
claims := token.Claims.(jwt.MapClaims)
|
||||||
|
claims["user_id"] = user.ID
|
||||||
|
claims["exp"] = time.Now().Add(time.Hour * 24).Unix()
|
||||||
|
|
||||||
|
t, err := token.SignedString([]byte("your-secret-key"))
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Could not login"})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert user.ID to string before storing in Redis
|
||||||
|
userIDStr := strconv.FormatUint(uint64(user.ID), 10)
|
||||||
|
err = redisClient.Set(t, []byte(userIDStr), 24*time.Hour)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Could not store token"})
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(fiber.Map{"token": t})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCurrentUser(db *gorm.DB) fiber.Handler {
|
||||||
|
return func(c *fiber.Ctx) error {
|
||||||
|
userID := c.Locals("user_id").(uint)
|
||||||
|
|
||||||
|
var user models.User
|
||||||
|
if err := db.First(&user, userID).Error; err != nil {
|
||||||
|
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "User not found"})
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(user)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateCurrentUser(db *gorm.DB) fiber.Handler {
|
||||||
|
return func(c *fiber.Ctx) error {
|
||||||
|
userID := c.Locals("user_id").(uint)
|
||||||
|
|
||||||
|
var input models.User
|
||||||
|
if err := c.BodyParser(&input); err != nil {
|
||||||
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid input"})
|
||||||
|
}
|
||||||
|
|
||||||
|
var user models.User
|
||||||
|
if err := db.First(&user, userID).Error; err != nil {
|
||||||
|
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "User not found"})
|
||||||
|
}
|
||||||
|
|
||||||
|
user.Email = input.Email
|
||||||
|
user.Phone = input.Phone
|
||||||
|
|
||||||
|
if err := db.Save(&user).Error; err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Could not update user"})
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(user)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetUserByID(db *gorm.DB) fiber.Handler {
|
||||||
|
return func(c *fiber.Ctx) error {
|
||||||
|
id := c.Params("id")
|
||||||
|
|
||||||
|
var user models.User
|
||||||
|
if err := db.First(&user, id).Error; err != nil {
|
||||||
|
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "User not found"})
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(user)
|
||||||
|
}
|
||||||
|
}
|
||||||
31
.history/middleware/auth_20240925162004.go
Normal file
31
.history/middleware/auth_20240925162004.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package middleware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"github.com/gofiber/storage/redis/v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AuthMiddleware(redisClient *redis.Storage) fiber.Handler {
|
||||||
|
return func(c *fiber.Ctx) error {
|
||||||
|
token := c.Get("Authorization")
|
||||||
|
if token == "" {
|
||||||
|
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Missing authorization token"})
|
||||||
|
}
|
||||||
|
|
||||||
|
userIDBytes, err := redisClient.Get(token)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Invalid or expired token"})
|
||||||
|
}
|
||||||
|
|
||||||
|
userIDStr := string(userIDBytes)
|
||||||
|
userID, err := strconv.ParseUint(userIDStr, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Invalid user ID format"})
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Locals("user_id", uint(userID))
|
||||||
|
return c.Next()
|
||||||
|
}
|
||||||
|
}
|
||||||
31
.history/middleware/auth_20240925162154.go
Normal file
31
.history/middleware/auth_20240925162154.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package middleware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"github.com/gofiber/storage/redis/v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AuthMiddleware(redisClient *redis.Storage) fiber.Handler {
|
||||||
|
return func(c *fiber.Ctx) error {
|
||||||
|
token := c.Get("Authorization")
|
||||||
|
if token == "" {
|
||||||
|
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Missing authorization token"})
|
||||||
|
}
|
||||||
|
|
||||||
|
userIDBytes, err := redisClient.Get(token)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Invalid or expired token"})
|
||||||
|
}
|
||||||
|
|
||||||
|
userIDStr := string(userIDBytes)
|
||||||
|
userID, err := strconv.ParseUint(userIDStr, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Invalid user ID format"})
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Locals("user_id", uint(userID))
|
||||||
|
return c.Next()
|
||||||
|
}
|
||||||
|
}
|
||||||
32
README.md
32
README.md
@ -1 +1,31 @@
|
|||||||
123
|
# TestFB
|
||||||
|
> 使用Go语言,实现用户登录、获取用户信息、修改用户信息。
|
||||||
|
|
||||||
|
## 工程要求:结构化工程,更加规范的代码编写。
|
||||||
|
## 工程使用的模块或技术:
|
||||||
|
1. Go语言
|
||||||
|
2. fiber框架
|
||||||
|
3. Gorm ORM框架
|
||||||
|
4. fiber下的storage/redis v3模块
|
||||||
|
5. JWT身份验证,存储在redis中
|
||||||
|
6. mysql,使用fiber下的storage/mysql v2模块
|
||||||
|
7. 日志,使用fiber自带的日志模块
|
||||||
|
|
||||||
|
## mysql模块
|
||||||
|
1. 数据库地址:localhost:3306
|
||||||
|
2. 数据库名称:testfb
|
||||||
|
3. 表名称:users
|
||||||
|
4. 字段:id, username, password, email, phone, created_at, updated_at
|
||||||
|
5. 密码字段需加密。
|
||||||
|
## redis模块
|
||||||
|
1. 存储用户的token信息
|
||||||
|
2. redis地址:localhost:6379
|
||||||
|
|
||||||
|
## 路由信息
|
||||||
|
1. 登录:POST /login
|
||||||
|
2. 获取当前用户信息: GET /user
|
||||||
|
3. 修改当前用户信息: PUT /user
|
||||||
|
4. 获取某个用户信息: GET /users/:id
|
||||||
|
|
||||||
|
## 其他
|
||||||
|
1. 日志保存在当前main.go目录下
|
||||||
@ -1,6 +1,7 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
@ -41,7 +42,9 @@ func Login(db *gorm.DB, redisClient *redis.Storage) fiber.Handler {
|
|||||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Could not login"})
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Could not login"})
|
||||||
}
|
}
|
||||||
|
|
||||||
err = redisClient.Set(t, user.ID, 24*time.Hour)
|
// Convert user.ID to string before storing in Redis
|
||||||
|
userIDStr := strconv.FormatUint(uint64(user.ID), 10)
|
||||||
|
err = redisClient.Set(t, []byte(userIDStr), 24*time.Hour)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Could not store token"})
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Could not store token"})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/gofiber/storage/redis/v3"
|
"github.com/gofiber/storage/redis/v3"
|
||||||
)
|
)
|
||||||
@ -12,12 +14,18 @@ func AuthMiddleware(redisClient *redis.Storage) fiber.Handler {
|
|||||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Missing authorization token"})
|
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Missing authorization token"})
|
||||||
}
|
}
|
||||||
|
|
||||||
userID, err := redisClient.Get(token)
|
userIDBytes, err := redisClient.Get(token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Invalid or expired token"})
|
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Invalid or expired token"})
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Locals("user_id", userID)
|
userIDStr := string(userIDBytes)
|
||||||
|
userID, err := strconv.ParseUint(userIDStr, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Invalid user ID format"})
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Locals("user_id", uint(userID))
|
||||||
return c.Next()
|
return c.Next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user