feat: jwt middleware

This commit is contained in:
fallen-angle
2022-02-12 16:32:34 +08:00
parent 2d43931fc8
commit 72ef5c92c4
10 changed files with 83 additions and 33 deletions

1
.gitignore vendored
View File

@@ -1,2 +1,3 @@
*.log
*.release
.idea

View File

@@ -2,6 +2,7 @@ package handler
import (
"fmt"
"nCovTrack-Backend/global"
"nCovTrack-Backend/models"
"nCovTrack-Backend/utils"
@@ -10,8 +11,10 @@ import (
)
func SaveArticleHandler(c *gin.Context) {
var articleSave models.Article
var articleSave models.BackArticle
c.ShouldBindJSON(&articleSave)
fmt.Println(utils.RenewToken("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NDMxMDA5MDAsImlhdCI6MTY0MzQyNDkwMH0.L8qNmbHJtV8fiKKxGbkZk3DrKBPdvhie_oFooH5hGOY"))
utils.Succ(c, map[string]string{"string": utils.GenerateToken(jwt.MapClaims{})})
global.Db.First(&articleSave)
fmt.Println(articleSave)
}

29
middleware/auth.go Normal file
View File

@@ -0,0 +1,29 @@
package middleware
import (
"github.com/gin-gonic/gin"
"nCovTrack-Backend/utils"
"net/http"
)
const UNAUTH_MSG = "unauthorized"
func Auth() gin.HandlerFunc {
return func(c *gin.Context) {
oldToken := c.Request.Header["Token"]
c.Writer.Header().Set("X-Token", "")
if len(oldToken) != 1 || oldToken[0] == "" {
utils.Err(c, http.StatusUnauthorized, http.StatusUnauthorized, UNAUTH_MSG)
c.Abort()
return
}
renewToken := utils.RenewToken(oldToken[0])
if renewToken == "" {
utils.Err(c, http.StatusUnauthorized, http.StatusUnauthorized, UNAUTH_MSG)
c.Abort()
return
}
c.Writer.Header().Set("X-Token", renewToken)
c.Next()
}
}

View File

@@ -2,7 +2,7 @@ package models
import "time"
type Article struct {
type BackArticle struct {
ID int `gorm:"primaryKey;column:id" json:"-"` // 文章id
CreateTime time.Time `gorm:"column:create_time" json:"createTime"` // 文章新建时间
CreateUser string `gorm:"column:create_user" json:"createUser"` // 文章创建者id

15
models/user.go Normal file
View File

@@ -0,0 +1,15 @@
package models
import "time"
type BackUser struct {
ID int `gorm:"primaryKey;column:id" json:"-"` // 用户ID
Username string `gorm:"column:username" json:"username"` // 用户真实姓名
Password string `gorm:"column:password" json:"password"` // 用户密码
Role int `gorm:"column:role" json:"role"` // 用户角色
Email string `gorm:"column:email" json:"email"` // 用户邮箱
Phone string `gorm:"column:phone" json:"phone"` // 用户手机号码
Aptitude string `gorm:"column:aptitude" json:"aptitude"` // 用户资质证明(图片URL)
RegisterTime time.Time `gorm:"column:register_time" json:"registerTime"` // 用户注册时间
Approver int `gorm:"column:approver" json:"approver"` // 注册审核人ID
}

View File

@@ -1,12 +1,12 @@
package router
import (
"nCovTrack-Backend/global"
"github.com/gin-gonic/gin"
"nCovTrack-Backend/handler"
)
func articleRouter() {
articleRouter := global.RootRouter.Group("/article")
func articlePrivateRouter(router *gin.RouterGroup) {
articleRouter := router.Group("/article")
{
articleRouter.POST("/save", handler.SaveArticleHandler)
}

View File

@@ -2,25 +2,21 @@ package router
import (
"nCovTrack-Backend/global"
"net/http"
"time"
"github.com/gin-gonic/gin"
"nCovTrack-Backend/middleware"
)
func BusiRouter() {
testRouter := global.RootRouter.Group("/test")
publicRouter := global.RootRouter.Group("")
privateRouter := global.RootRouter.Group("")
privateRouter.Use(middleware.Auth())
// Public
{
testRouter.GET("/count", func(c *gin.Context) {
time.Sleep(800 * time.Millisecond)
c.String(http.StatusOK, "OK")
})
//testRouter.GET("/test", statistics.GetChinaNCovStatistic())
//testRouter.GET("/redis", func(c *gin.Context) {
// data := statistics.GetAllProvienceData(statistics.SORT_NOW_CONFIRM)
// Succ(c, data)
//})
statisticRouter(publicRouter)
}
// Private
{
articlePrivateRouter(privateRouter)
}
statisticRouter()
articleRouter()
}

View File

@@ -1,12 +1,12 @@
package router
import (
"nCovTrack-Backend/global"
"github.com/gin-gonic/gin"
"nCovTrack-Backend/handler"
)
func statisticRouter() {
statisticsRouter := global.RootRouter.Group("/statistics")
func statisticRouter(router *gin.RouterGroup) {
statisticsRouter := router.Group("/statistics")
{
statisticsRouter.GET("/provience/:sort", handler.ProvienceDataHandler)
statisticsRouter.GET("/city/:sort", handler.CityDataHandler)

View File

@@ -10,7 +10,7 @@ import (
var JWT_KEY = []byte(global.ServerSettings.Jwt.Secret)
// Generate token for user
// GenerateToken Generate token for user
// Return: token generated
func GenerateToken(claims jwt.MapClaims) string {
claims["exp"] = time.Now().Add(15 * 24 * time.Hour).Unix()
@@ -23,31 +23,33 @@ func GenerateToken(claims jwt.MapClaims) string {
return tokenStr
}
// Renew user's token
// RenewToken Renew user's token
// tokenStr: user request token
// Return:
// BlankString: token is invalid or token is expired out of allowed time;
// OldToken: token is not need to renew;
// NewToekn: token is renew;
// NewToken: token is renew;
func RenewToken(tokenStr string) string {
token, err := jwt.Parse(tokenStr, func(t *jwt.Token) (interface{}, error) {
return JWT_KEY, nil
})
// Token is invalid
if err != nil {
switch err.(*jwt.ValidationError).Errors {
case jwt.ValidationErrorSignatureInvalid:
return ""
case jwt.ValidationErrorIssuedAt:
return ""
}
}
claims := token.Claims.(jwt.MapClaims)
expireAt := time.Unix(int64(claims["exp"].(float64)), 0)
expireDuration := expireAt.Sub(time.Now())
// Token is out of allow expire duration
if expireDuration.Hours() < float64(-global.ServerSettings.Jwt.RenewExpireDays*24) {
if expireDuration.Hours() < -float64(global.ServerSettings.Jwt.RenewExpireDays*24) {
return ""
}
// Token not need renew

View File

@@ -18,3 +18,7 @@ func Error(c *gin.Context, status int, code int, msg interface{}, data interface
func Succ(c *gin.Context, data interface{}) {
Success(c, http.StatusOK, "success", data)
}
func Err(c *gin.Context, status int, code int, msg interface{}) {
c.JSON(status, models.GinResponse{Code: code, Msg: msg})
}