Files
nCovTrack-Backend/middleware/auth.go
2022-04-13 19:48:10 +08:00

63 lines
2.1 KiB
Go

package middleware
import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt/v4"
"nCovTrack-Backend/global"
"nCovTrack-Backend/utils"
"net/http"
"strconv"
"time"
)
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
}
// Write the field of token to request header
claims := utils.ParseClaims(oldToken[0])
c.Request.Header.Set("role", fmt.Sprint(claims["role"]))
c.Request.Header.Set("email", claims["email"].(string))
c.Request.Header.Set("id", fmt.Sprint(claims["id"]))
c.Request.Header.Set("role", claims["role"].(string))
// renew token, and judge the token's iat is expired or not
renewToken := utils.RenewToken(oldToken[0])
if renewToken == "" || !validAccountIssue(claims) {
utils.Err(c, http.StatusUnauthorized, http.StatusUnauthorized, UNAUTH_MSG)
c.Abort()
return
}
c.Writer.Header().Set("X-Token", renewToken)
c.Next()
}
}
// validAccountIssue validate token is valid or not
// If user change password, or logoff on all password, we need to judge use's token is valid?
// Due to the token is no status, so we need to record something on the server-end.
// We use the "IssueAt" field of token, to judge token expired or not.
// TODO: Move this to jwt utils
func validAccountIssue(claims jwt.MapClaims) bool {
iafStr := global.Redis.HGet(global.CHANGEPWD_REDIS_KEY, claims["email"].(string)).Val()
if iafStr == "" {
return true
}
iaf, _ := strconv.Atoi(iafStr)
// Due to we allow token renew, although it was expired, so the token validity period will more than token's validity period
tokenMaxValidSeconds := (global.TOKEN_EXPIRE_DAYS + global.ServerSettings.Jwt.RenewExpireDays) * 24 * 60 * 60
if time.Now().Unix()-int64(iaf) > int64(tokenMaxValidSeconds) {
global.Redis.HDel(global.CHANGEPWD_REDIS_KEY, claims["email"].(string))
return true
}
return int(claims["iat"].(float64)) > iaf
}