feat: add jwt

This commit is contained in:
fallen-angle
2022-02-10 17:08:42 +08:00
parent 77f7d0caad
commit 2d43931fc8
10 changed files with 165 additions and 5 deletions

View File

@@ -9,6 +9,7 @@ type ServerConfig struct {
LogPath string `yaml:"logPath"` LogPath string `yaml:"logPath"`
MySQL MySQLConfig `yaml:"mysql"` MySQL MySQLConfig `yaml:"mysql"`
Redis RedisConfig `yaml:"redis"` Redis RedisConfig `yaml:"redis"`
Jwt JwtConfig `yaml:"jwt"`
} }
type MySQLConfig struct { type MySQLConfig struct {
@@ -24,3 +25,9 @@ type RedisConfig struct {
Port int `yaml:"port"` Port int `yaml:"port"`
Password string `yaml:"password"` Password string `yaml:"password"`
} }
type JwtConfig struct {
Secret string `yaml:"secret"`
RenewExpireDays uint `yaml:"renewExpireDays"`
RenewAheadDays uint `yaml:"renewAheadDays"`
}

17
handler/article.go Normal file
View File

@@ -0,0 +1,17 @@
package handler
import (
"fmt"
"nCovTrack-Backend/models"
"nCovTrack-Backend/utils"
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt/v4"
)
func SaveArticleHandler(c *gin.Context) {
var articleSave models.Article
c.ShouldBindJSON(&articleSave)
fmt.Println(utils.RenewToken("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NDMxMDA5MDAsImlhdCI6MTY0MzQyNDkwMH0.L8qNmbHJtV8fiKKxGbkZk3DrKBPdvhie_oFooH5hGOY"))
utils.Succ(c, map[string]string{"string": utils.GenerateToken(jwt.MapClaims{})})
}

View File

@@ -6,12 +6,13 @@ import (
"gorm.io/driver/mysql" "gorm.io/driver/mysql"
"gorm.io/gorm" "gorm.io/gorm"
"gorm.io/gorm/schema"
) )
func initMySQL() { func initMySQL() {
mysqlConf := global.ServerSettings.MySQL mysqlConf := global.ServerSettings.MySQL
dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local", mysqlConf.Username, mysqlConf.Password, mysqlConf.Host, mysqlConf.Port, mysqlConf.Database) dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local", mysqlConf.Username, mysqlConf.Password, mysqlConf.Host, mysqlConf.Port, mysqlConf.Database)
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{NamingStrategy: schema.NamingStrategy{SingularTable: true}})
if err != nil { if err != nil {
panic(err) panic(err)
} }

View File

@@ -49,10 +49,27 @@ func GinRecovery(stack bool) gin.HandlerFunc {
} }
utils.RequestLogError(logParams...) utils.RequestLogError(logParams...)
c.AbortWithStatus(http.StatusInternalServerError) c.AbortWithStatus(http.StatusInternalServerError)
fmt.Println(err) fmt.Printf("\n%s\n", err)
fmt.Printf("\n%s\n", debug.Stack()) fmt.Printf("\n%s\n", cutStack(debug.Stack()))
} }
}() }()
c.Next() c.Next()
} }
} }
func cutStack(stack []byte) string {
stackStr := string(stack)
line := 0
lastLineCharIndex := 0
for index, char := range stackStr {
if char == '\n' {
line++
}
if line == 7 {
lastLineCharIndex = index + 1
break
}
}
fmt.Println(stackStr[lastLineCharIndex:])
return ""
}

16
models/article.go Normal file
View File

@@ -0,0 +1,16 @@
package models
import "time"
type Article 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
ModifyTime time.Time `gorm:"column:modify_time" json:"modifyTime"` // 文章最后更新时间
ModifyUser string `gorm:"column:modify_user" json:"modifyUser"` // 文章最后更新者id
Title string `gorm:"column:title" json:"title"` // 文章标题
Tags string `gorm:"column:tags" json:"tags"` // 文章Tag
Resume string `gorm:"column:resume" json:"resume"` // 文章简述
Cover string `gorm:"column:cover" json:"cover"` // 文章封面
Content string `gorm:"column:content" json:"content"` // 文章内容(如有需要可迁移至对象存储)
}

13
router/article.go Normal file
View File

@@ -0,0 +1,13 @@
package router
import (
"nCovTrack-Backend/global"
"nCovTrack-Backend/handler"
)
func articleRouter() {
articleRouter := global.RootRouter.Group("/article")
{
articleRouter.POST("/save", handler.SaveArticleHandler)
}
}

View File

@@ -22,4 +22,5 @@ func BusiRouter() {
//}) //})
} }
statisticRouter() statisticRouter()
articleRouter()
} }

View File

@@ -0,0 +1,17 @@
package article
import (
"nCovTrack-Backend/global"
"nCovTrack-Backend/models"
)
func GetArticleList() []models.Article {
return make([]models.Article, 0)
}
func SaveArticle(article models.Article) {
// 前端校验
// articlea := &models.Article{Content: "#Ceshi", Cover: "https://www.baidu.com/link?url=AWfrkr2rXUGVmKuD08cYx7GwAfQw7qXy_ZczQuH9N_raTP0_eRTv4eZgsdYhtMhS8F7nVl9WfdF01byCD5DAKK&wd=&eqid=b50bb6b100004750000000056202107a", Resume: "sss", Tags: "s", Title: "title", CreateUser: "1", ModifyUser: "1", CreateTime: time.Now(), ModifyTime: time.Now()}
tx := global.Db.Create(article)
print(tx)
}

View File

@@ -9,10 +9,15 @@ mysql:
host: myhost.fallen-angle.com host: myhost.fallen-angle.com
port: 3306 port: 3306
username: root username: root
password: 13291004986@lm password: 13291004986
database: nCovTrack database: ncov_track
redis: redis:
host: myhost.fallen-angle.com host: myhost.fallen-angle.com
port: 6379 port: 6379
password: wzl20001001 password: wzl20001001
jwt:
secret: bWF5YmVJYWxzb3NhbWV0b2JlZm9yZe
renewExpireDays: 7
renewAheadDays: 3

66
utils/jwt.go Normal file
View File

@@ -0,0 +1,66 @@
package utils
import (
"fmt"
"nCovTrack-Backend/global"
"time"
"github.com/golang-jwt/jwt/v4"
)
var JWT_KEY = []byte(global.ServerSettings.Jwt.Secret)
// Generate token for user
// Return: token generated
func GenerateToken(claims jwt.MapClaims) string {
claims["exp"] = time.Now().Add(15 * 24 * time.Hour).Unix()
claims["iat"] = time.Now().Unix()
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
tokenStr, err := token.SignedString(JWT_KEY)
if err != nil {
panic(err)
}
return tokenStr
}
// 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;
func RenewToken(tokenStr string) string {
token, err := jwt.Parse(tokenStr, func(t *jwt.Token) (interface{}, error) {
return JWT_KEY, nil
})
// Token is invalid
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) {
return ""
}
// Token not need renew
if expireDuration.Hours() > float64(global.ServerSettings.Jwt.RenewAheadDays*24) {
return tokenStr
}
fmt.Println(expireDuration)
claims["exp"] = time.Now().Add(15 * 24 * time.Hour).Unix()
token = jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
tokenStr, err = token.SignedString(JWT_KEY)
if err != nil {
panic(err)
}
return tokenStr
}