nezha/cmd/dashboard/controller/jwt.go

111 lines
2.8 KiB
Go

package controller
import (
"log"
"time"
jwt "github.com/appleboy/gin-jwt/v2"
"github.com/gin-gonic/gin"
"github.com/naiba/nezha/model"
"github.com/naiba/nezha/service/singleton"
"golang.org/x/crypto/bcrypt"
)
func initParams() *jwt.GinJWTMiddleware {
return &jwt.GinJWTMiddleware{
Realm: singleton.Conf.SiteName,
Key: []byte(singleton.Conf.SecretKey),
Timeout: time.Hour,
MaxRefresh: time.Hour,
IdentityKey: model.CtxKeyAuthorizedUser,
PayloadFunc: payloadFunc(),
IdentityHandler: identityHandler(),
Authenticator: authenticator(),
Authorizator: authorizator(),
Unauthorized: unauthorized(),
TokenLookup: "header: Authorization, query: token, cookie: jwt",
TokenHeadName: "Bearer",
TimeFunc: time.Now,
}
}
func handlerMiddleWare(authMiddleware *jwt.GinJWTMiddleware) gin.HandlerFunc {
return func(context *gin.Context) {
errInit := authMiddleware.MiddlewareInit()
if errInit != nil {
log.Fatal("authMiddleware.MiddlewareInit() Error:" + errInit.Error())
}
}
}
func payloadFunc() func(data interface{}) jwt.MapClaims {
return func(data interface{}) jwt.MapClaims {
if v, ok := data.(*model.User); ok {
return jwt.MapClaims{
model.CtxKeyAuthorizedUser: v.ID,
}
}
return jwt.MapClaims{}
}
}
func identityHandler() func(c *gin.Context) interface{} {
return func(c *gin.Context) interface{} {
claims := jwt.ExtractClaims(c)
userId := claims[model.CtxKeyAuthorizedUser].(uint64)
var user model.User
if err := singleton.DB.First(&user, userId).Error; err != nil {
return nil
}
return &user
}
}
// login test godoc
// @Summary ping example
// @Schemes
// @Description do ping
// @Tags example
// @Accept json
// @Produce json
// @Success 200 {string} Helloworld
// @Router /example/login [get]
func authenticator() func(c *gin.Context) (interface{}, error) {
return func(c *gin.Context) (interface{}, error) {
var loginVals model.LoginRequest
if err := c.ShouldBind(&loginVals); err != nil {
return "", jwt.ErrMissingLoginValues
}
var user model.User
if err := singleton.DB.Select("id").Where("username = ?", loginVals.Username).First(&user).Error; err != nil {
return nil, jwt.ErrFailedAuthentication
}
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(loginVals.Password)); err != nil {
return nil, jwt.ErrFailedAuthentication
}
return &user, nil
}
}
func authorizator() func(data interface{}, c *gin.Context) bool {
return func(data interface{}, c *gin.Context) bool {
_, ok := data.(*model.User)
return ok
}
}
func unauthorized() func(c *gin.Context, code int, message string) {
return func(c *gin.Context, code int, message string) {
c.JSON(code, model.CommonResponse{
Success: false,
Error: model.CommonError{
Code: model.ApiErrorUnauthorized,
},
})
}
}