fiber框架token校验

文档地址 https://github.com/gofiber/jwt


package main

import (
	"time"

	"github.com/dgrijalva/jwt-go"
	"github.com/gofiber/fiber"
	"github.com/gofiber/fiber/middleware"
	jwtware "github.com/gofiber/jwt"
)

const jwtSecret = "asecret"

//token验证
func authRequired() func(ctx *fiber.Ctx) {
	return jwtware.New(jwtware.Config{
		SigningKey: []byte(jwtSecret),
		ErrorHandler: func(ctx *fiber.Ctx, err error) {
			ctx.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
				"err": "Unauthorized",
			})
		},
	})
}

func main() {
	app := fiber.New()
	app.Use(middleware.Logger()) //查看访问的接口

	app.Get("/", func(ctx *fiber.Ctx) {
		ctx.Send("hello")
	})

	app.Post("/login", login)
	app.Get("/hello", authRequired(), func(ctx *fiber.Ctx) {

		ctx.Send("hello")
	})

	err := app.Listen(3000)
	if err != nil {
		panic(err)
	}

}

//登录
func login(ctx *fiber.Ctx) {
	type request struct {
		Email    string `json:"email"`
		Password string `json:"password"`
	}
	var body request
	err := ctx.BodyParser(&body)
	if err != nil {
		ctx.Status(fiber.StatusBadRequest).JSON(fiber.Map{
			"error": "cannot parse json",
		})
		return
	}
	if body.Email != "bob@gmail.com" || body.Password != "password123" {
		ctx.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
			"error": "Bad  Credentials",
		})
		return
	}

	// Create token
	token := jwt.New(jwt.SigningMethodHS256)

	// Set claims
	claims := token.Claims.(jwt.MapClaims)
	claims["name"] = "wangmin"
	claims["admin"] = true
	claims["exp"] = time.Now().Add(time.Hour * 72).Unix()

	// Generate encoded token and send it as response.
	t, err := token.SignedString([]byte(jwtSecret))
	if err != nil {
		ctx.SendStatus(fiber.StatusInternalServerError)
		return
	}

	ctx.Status(fiber.StatusOK).JSON(fiber.Map{
		"token": t,
		"user": struct {
			Id    int    `json:"id"`
			Email string `json:"email"`
		}{
			Id:    1,
			Email: "bob@gmail.com",
		},
	})
}

### Golang 中使用 GORM 和 JWT 实现用户鉴权 #### 创建项目结构 为了实现完整的用户鉴权功能,首先需要创建合理的项目目录结构。通常情况下会包含如下文件夹: - `models`:用于定义数据库模型。 - `routes`:负责处理 HTTP 请求并调用相应的控制器逻辑。 - `controllers`:业务逻辑层,处理具体的请求操作。 - `middlewares`:中间件用来拦截请求,在此可以加入身份验证机制。 #### 安装依赖包 确保安装必要的库来支持开发工作: ```bash go mod init go-lang-gorm-jwt-auth go get github.com/gofiber/fiber/v2 go get github.com/golang-jwt/jwt/v5 go get gorm.io/driver/mysql go get gorm.io/gorm ``` #### 数据库配置与初始化 在应用程序启动时连接到 MySQL 数据库,并设置自动迁移以保持表结构最新。 ```go // main.go package main import ( "gorm.io/driver/mysql" "gorm.io/gorm" ) func InitDB() *gorm.DB { dsn := "username:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local" db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err != nil { panic("failed to connect database") } // 自动迁移模式 db.AutoMigrate(&User{}) return db } ``` #### 用户模型设计 定义一个简单的 User 结构体表示用户实体类。 ```go // models/user.go type User struct { ID uint `json:"id"` Username string `json:"username" gorm:"uniqueIndex"` Password string `json:"-"` } func (u *User) HashPassword(password string) error { bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14) u.Password = string(bytes) return err } func CheckPasswordHash(password, hash string) bool { err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) return err == nil } ``` #### 登录接口实现 编写登录 API 来接收用户名密码参数,校验成功后返回带有签名的 JSON Web Token 给客户端。 ```go // controllers/auth_controller.go func Login(c *fiber.Ctx) error { var data map[string]string if err := c.BodyParser(&data); err != nil { return err } user := new(models.User) if err := config.DB.Where("username=?", data["username"]).First(user).Error; err != nil { return fiber.NewError(fiber.StatusUnauthorized, "Invalid credentials") } if !CheckPasswordHash(data["password"], user.Password) { return fiber.NewError(fiber.StatusUnauthorized, "Invalid credentials") } tokenString, _ := GenerateToken(user.ID, user.Username) response := Response{ Status: true, Message: "Login successful", Data: map[string]string{"token": tokenString}, } return c.JSON(response) } ``` #### 验证器 Middleware 的构建 创建名为 AuthMiddleware 的函数作为 Fiber 框架下的中间件组件,它会在每次访问受保护资源之前执行,从而确保只有合法持有有效令牌的人才能继续前进。 ```go // middlewares/auth_middleware.go func AuthMiddleware(next fiber.Handler) fiber.Handler { return func(c *fiber.Ctx) error { authHeader := c.Get("Authorization") if authHeader == "" { return c.SendStatus(fiber.StatusBadRequest) } idToken := strings.Split(authHeader, "Bearer ")[1] claims := &Claims{} _, err := jwt.ParseWithClaims(idToken, claims, func(token *jwt.Token) (interface{}, error) { return []byte(os.Getenv("SECRET_KEY")), nil }) if err != nil || time.Now().Unix()-claims.IssuedAt > int64(time.Hour.Seconds())*24 { // 过期时间判断 return c.SendStatus(fiber.StatusUnauthorized) } ctx := context.WithValue(c.Context(), "user", claims.Subject) c.SetContext(ctx) return next(c) } } ``` #### 受限路由保护 最后一步是在应用入口处注册所有公开可用的服务端点以及那些仅允许经过授权后的用户才可以使用的私有路径。 ```go app.Post("/login", controller.Login) protectedGroup := app.Group("/", middleware.AuthMiddleware) protectedGroup.Get("/profile", controller.GetUserProfile) ``` 通过上述步骤已经完成了一个基本版的支持 RESTful API 形式的 Go 应用程序,该实例展示了怎样利用 GORM ORM 工具简化对关系型数据库的操作流程;同时也介绍了如何借助于 JWT 技术保障网络通信安全可靠[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值