认证中间件 原创
现在我们开发完了用户管理模块,改模块是需要用户登录认证过后才有操作权限。
为此,需要专门开发一个中间件来做鉴权,避免为每个接口都配置权限。
1、开发中间件
在 internal/app/middlewares
中新增 auth.go
文件,写入以下内容:
go
package middlewares
import (
"github.com/gin-gonic/gin"
"github.com/joker-bai/kubemana/internal/app/models"
"github.com/joker-bai/kubemana/pkg/app"
"github.com/joker-bai/kubemana/pkg/errorcode"
"github.com/joker-bai/kubemana/pkg/jwt"
)
// Auth 认证中间件
func AuthJWT() gin.HandlerFunc {
return func(ctx *gin.Context) {
// 从标头 Authorization:Bearer xxxxx 中获取信息,并验证 JWT 的准确性
claims, err := jwt.NewJWT().ParserToken(ctx)
response := app.NewResponse(ctx)
// JWT 解析失败,有错误发生
if err != nil {
response.ToErrorResponse(errorcode.UnauthorizedTokenError)
return
}
// JWT 解析成功,设置用户信息
users := models.User{}
userModel := users.GetUserByID(claims.UserID)
if userModel.ID == 0 {
response.ToErrorResponse(errorcode.UnauthorizedTokenError)
return
}
// 将用户信息存入 gin.context 里,后续 auth 包将从这里拿到当前用户数据
ctx.Set("current_user_id", userModel.GetStringID())
ctx.Set("current_user_name", userModel.Username)
ctx.Set("current_user", userModel)
ctx.Next()
}
}
首先从请求头里获取 Token 认证信息,然后解析 Token,如果解析失败则认证失败,解析成功再到数据库中判断用户是否真的存在,只有存在了才认证通过。
上面使用到 users.GetUserByID()
方法,为此,我们需要在 internal/app/models/user.go
中增加如下方法:
go
// 通过ID查找用户
func (u *User) GetUserByID(id string) User {
var user = &User{}
global.DB.Where("id", id).First(&user)
return *user
}
2、修改路由
现在我们修改一下路由,把用户管理加入权限校验,修改 initialize/router.go 文件,如下:
go
package initialize
import (
"github.com/gin-gonic/gin"
_ "github.com/joker-bai/kubemana/docs"
"github.com/joker-bai/kubemana/internal/app/middlewares"
"github.com/joker-bai/kubemana/internal/app/routers"
swaggerFiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
)
type injector interface {
Inject(router *gin.RouterGroup)
}
func (s *Engine) injectRouterGroup(router *gin.RouterGroup) {
// public
for _, r := range []injector{
new(routers.AuthRouter),
} {
r.Inject(router.Group("/api/v1"))
}
// auth
for _, r := range []injector{
new(routers.UserRouter),
} {
r.Inject(router.Group("/api/v1", middlewares.AuthJWT()))
}
for _, r := range []injector{
new(routers.HelloWorldRouter),
} {
r.Inject(router.Group("/api"))
}
router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
}
我们在路由组里加了 middlewares.AuthJWT()
表示只有这个组需要使用这个中间件,如果要加在全局,就在 initialize/server.go
中配置。
3、测试一下
(1)先不填写 token,直接测试获取用户列表,输出如下:
给我们报服务器内部错误,从日志来看实则是权限校验未通过,如下:
go
"error":"invalid WriteHeader code 100005"
(2)添加 token 进行测试
在通过用户登录获取 token,如下:
然后将 token 加入到列出用户的接口中,如下:
现在再执行接口,就能正常获取到用户信息了,如下:
4、代码标记
开发完本节内容,记得给代码标记一下:
go
$ git add .
$ git commit -m "新增认证中间件"