feat: jwt middleware
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
|||||||
*.log
|
*.log
|
||||||
*.release
|
*.release
|
||||||
|
.idea
|
||||||
@@ -2,6 +2,7 @@ package handler
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"nCovTrack-Backend/global"
|
||||||
"nCovTrack-Backend/models"
|
"nCovTrack-Backend/models"
|
||||||
"nCovTrack-Backend/utils"
|
"nCovTrack-Backend/utils"
|
||||||
|
|
||||||
@@ -10,8 +11,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func SaveArticleHandler(c *gin.Context) {
|
func SaveArticleHandler(c *gin.Context) {
|
||||||
var articleSave models.Article
|
var articleSave models.BackArticle
|
||||||
c.ShouldBindJSON(&articleSave)
|
c.ShouldBindJSON(&articleSave)
|
||||||
fmt.Println(utils.RenewToken("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NDMxMDA5MDAsImlhdCI6MTY0MzQyNDkwMH0.L8qNmbHJtV8fiKKxGbkZk3DrKBPdvhie_oFooH5hGOY"))
|
fmt.Println(utils.RenewToken("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NDMxMDA5MDAsImlhdCI6MTY0MzQyNDkwMH0.L8qNmbHJtV8fiKKxGbkZk3DrKBPdvhie_oFooH5hGOY"))
|
||||||
utils.Succ(c, map[string]string{"string": utils.GenerateToken(jwt.MapClaims{})})
|
utils.Succ(c, map[string]string{"string": utils.GenerateToken(jwt.MapClaims{})})
|
||||||
|
global.Db.First(&articleSave)
|
||||||
|
fmt.Println(articleSave)
|
||||||
}
|
}
|
||||||
|
|||||||
29
middleware/auth.go
Normal file
29
middleware/auth.go
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ package models
|
|||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
type Article struct {
|
type BackArticle struct {
|
||||||
ID int `gorm:"primaryKey;column:id" json:"-"` // 文章id
|
ID int `gorm:"primaryKey;column:id" json:"-"` // 文章id
|
||||||
CreateTime time.Time `gorm:"column:create_time" json:"createTime"` // 文章新建时间
|
CreateTime time.Time `gorm:"column:create_time" json:"createTime"` // 文章新建时间
|
||||||
CreateUser string `gorm:"column:create_user" json:"createUser"` // 文章创建者id
|
CreateUser string `gorm:"column:create_user" json:"createUser"` // 文章创建者id
|
||||||
|
|||||||
15
models/user.go
Normal file
15
models/user.go
Normal 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
|
||||||
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
package router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"nCovTrack-Backend/global"
|
"github.com/gin-gonic/gin"
|
||||||
"nCovTrack-Backend/handler"
|
"nCovTrack-Backend/handler"
|
||||||
)
|
)
|
||||||
|
|
||||||
func articleRouter() {
|
func articlePrivateRouter(router *gin.RouterGroup) {
|
||||||
articleRouter := global.RootRouter.Group("/article")
|
articleRouter := router.Group("/article")
|
||||||
{
|
{
|
||||||
articleRouter.POST("/save", handler.SaveArticleHandler)
|
articleRouter.POST("/save", handler.SaveArticleHandler)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,25 +2,21 @@ package router
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"nCovTrack-Backend/global"
|
"nCovTrack-Backend/global"
|
||||||
"net/http"
|
"nCovTrack-Backend/middleware"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func BusiRouter() {
|
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) {
|
statisticRouter(publicRouter)
|
||||||
time.Sleep(800 * time.Millisecond)
|
}
|
||||||
c.String(http.StatusOK, "OK")
|
|
||||||
})
|
// Private
|
||||||
//testRouter.GET("/test", statistics.GetChinaNCovStatistic())
|
{
|
||||||
//testRouter.GET("/redis", func(c *gin.Context) {
|
articlePrivateRouter(privateRouter)
|
||||||
// data := statistics.GetAllProvienceData(statistics.SORT_NOW_CONFIRM)
|
|
||||||
// Succ(c, data)
|
|
||||||
//})
|
|
||||||
}
|
}
|
||||||
statisticRouter()
|
|
||||||
articleRouter()
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"nCovTrack-Backend/global"
|
"github.com/gin-gonic/gin"
|
||||||
"nCovTrack-Backend/handler"
|
"nCovTrack-Backend/handler"
|
||||||
)
|
)
|
||||||
|
|
||||||
func statisticRouter() {
|
func statisticRouter(router *gin.RouterGroup) {
|
||||||
statisticsRouter := global.RootRouter.Group("/statistics")
|
statisticsRouter := router.Group("/statistics")
|
||||||
{
|
{
|
||||||
statisticsRouter.GET("/provience/:sort", handler.ProvienceDataHandler)
|
statisticsRouter.GET("/provience/:sort", handler.ProvienceDataHandler)
|
||||||
statisticsRouter.GET("/city/:sort", handler.CityDataHandler)
|
statisticsRouter.GET("/city/:sort", handler.CityDataHandler)
|
||||||
|
|||||||
10
utils/jwt.go
10
utils/jwt.go
@@ -10,7 +10,7 @@ import (
|
|||||||
|
|
||||||
var JWT_KEY = []byte(global.ServerSettings.Jwt.Secret)
|
var JWT_KEY = []byte(global.ServerSettings.Jwt.Secret)
|
||||||
|
|
||||||
// Generate token for user
|
// GenerateToken Generate token for user
|
||||||
// Return: token generated
|
// Return: token generated
|
||||||
func GenerateToken(claims jwt.MapClaims) string {
|
func GenerateToken(claims jwt.MapClaims) string {
|
||||||
claims["exp"] = time.Now().Add(15 * 24 * time.Hour).Unix()
|
claims["exp"] = time.Now().Add(15 * 24 * time.Hour).Unix()
|
||||||
@@ -23,31 +23,33 @@ func GenerateToken(claims jwt.MapClaims) string {
|
|||||||
return tokenStr
|
return tokenStr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Renew user's token
|
// RenewToken Renew user's token
|
||||||
// tokenStr: user request token
|
// tokenStr: user request token
|
||||||
// Return:
|
// Return:
|
||||||
// BlankString: token is invalid or token is expired out of allowed time;
|
// BlankString: token is invalid or token is expired out of allowed time;
|
||||||
// OldToken: token is not need to renew;
|
// OldToken: token is not need to renew;
|
||||||
// NewToekn: token is renew;
|
// NewToken: token is renew;
|
||||||
func RenewToken(tokenStr string) string {
|
func RenewToken(tokenStr string) string {
|
||||||
token, err := jwt.Parse(tokenStr, func(t *jwt.Token) (interface{}, error) {
|
token, err := jwt.Parse(tokenStr, func(t *jwt.Token) (interface{}, error) {
|
||||||
return JWT_KEY, nil
|
return JWT_KEY, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
// Token is invalid
|
// Token is invalid
|
||||||
|
if err != nil {
|
||||||
switch err.(*jwt.ValidationError).Errors {
|
switch err.(*jwt.ValidationError).Errors {
|
||||||
case jwt.ValidationErrorSignatureInvalid:
|
case jwt.ValidationErrorSignatureInvalid:
|
||||||
return ""
|
return ""
|
||||||
case jwt.ValidationErrorIssuedAt:
|
case jwt.ValidationErrorIssuedAt:
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
claims := token.Claims.(jwt.MapClaims)
|
claims := token.Claims.(jwt.MapClaims)
|
||||||
expireAt := time.Unix(int64(claims["exp"].(float64)), 0)
|
expireAt := time.Unix(int64(claims["exp"].(float64)), 0)
|
||||||
expireDuration := expireAt.Sub(time.Now())
|
expireDuration := expireAt.Sub(time.Now())
|
||||||
|
|
||||||
// Token is out of allow expire duration
|
// 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 ""
|
return ""
|
||||||
}
|
}
|
||||||
// Token not need renew
|
// Token not need renew
|
||||||
|
|||||||
@@ -18,3 +18,7 @@ func Error(c *gin.Context, status int, code int, msg interface{}, data interface
|
|||||||
func Succ(c *gin.Context, data interface{}) {
|
func Succ(c *gin.Context, data interface{}) {
|
||||||
Success(c, http.StatusOK, "success", data)
|
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})
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user