Feat: Add JWT config, auth middleware, and token parsing using username.
Signed-off-by: Goldbro233 <bowensun_06@outlook.com>
This commit is contained in:
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
config/config.yml
|
||||
|
||||
/.idea/
|
||||
/qodana.yaml
|
||||
@@ -22,6 +22,9 @@ type Config struct {
|
||||
Bcrypt struct {
|
||||
Cost int
|
||||
}
|
||||
Jwtconfig struct {
|
||||
Secret string
|
||||
}
|
||||
}
|
||||
|
||||
var AppConfig *Config
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"GinTutorial/models"
|
||||
"GinTutorial/utils"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -44,7 +43,7 @@ func Register(ctx *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
token, err := utils.GenerateJWT(strconv.Itoa(int(user.ID)))
|
||||
token, err := utils.GenerateJWT(user.Username)
|
||||
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusInternalServerError, gin.H{
|
||||
@@ -87,7 +86,7 @@ func Login(ctx *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
token, err := utils.GenerateJWT(strconv.Itoa(int(user.ID)))
|
||||
token, err := utils.GenerateJWT(user.Username)
|
||||
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusInternalServerError, gin.H{
|
||||
|
||||
43
controllers/ex_controller.go
Normal file
43
controllers/ex_controller.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"GinTutorial/global"
|
||||
"GinTutorial/models"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func CreateExchangeRate(ctx *gin.Context) {
|
||||
var exchangeRate models.ExchangeRate
|
||||
|
||||
if err := ctx.ShouldBindJSON(&exchangeRate); err != nil {
|
||||
ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
exchangeRate.Date = time.Now()
|
||||
|
||||
if err := global.Db.AutoMigrate(&exchangeRate); err != nil {
|
||||
ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
if err := global.Db.Create(&exchangeRate).Error; err != nil {
|
||||
ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusCreated, gin.H{"data": exchangeRate})
|
||||
}
|
||||
|
||||
func GetExchangeRates(ctx *gin.Context) {
|
||||
var exchangeRates []models.ExchangeRate
|
||||
|
||||
if err := global.Db.Find(&exchangeRates).Error; err != nil {
|
||||
ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
ctx.JSON(http.StatusOK, gin.H{"data": exchangeRates})
|
||||
}
|
||||
28
middlewares/auth_middleware.go
Normal file
28
middlewares/auth_middleware.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package middlewares
|
||||
|
||||
import (
|
||||
"GinTutorial/utils"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func AuthMiddleWare() gin.HandlerFunc {
|
||||
return func(ctx *gin.Context) {
|
||||
token := ctx.GetHeader("Authorization")
|
||||
if token == "" {
|
||||
ctx.JSON(http.StatusUnauthorized, gin.H{"message": "Token is empty"})
|
||||
ctx.Abort()
|
||||
return
|
||||
}
|
||||
username, err := utils.ParseToken(token)
|
||||
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid Token"})
|
||||
ctx.Abort()
|
||||
return
|
||||
}
|
||||
ctx.Set("username", username)
|
||||
ctx.Next()
|
||||
}
|
||||
}
|
||||
11
models/ex_rate.go
Normal file
11
models/ex_rate.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
type ExchangeRate struct {
|
||||
ID uint `gorm:"primary_key" json:"_id"`
|
||||
FromCurrency string `json:"from_currency" binding:"required"`
|
||||
ToCurrency string `json:"to_currency" binding:"required"`
|
||||
Rate float64 `json:"rate" binding:"required"`
|
||||
Date time.Time `json:"date"`
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package router
|
||||
|
||||
import (
|
||||
"GinTutorial/controllers"
|
||||
"GinTutorial/middlewares"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -17,6 +18,13 @@ func SetupRouter() *gin.Engine {
|
||||
auth.POST("/login", controllers.Login)
|
||||
auth.POST("/register", controllers.Register)
|
||||
}
|
||||
|
||||
ex := v1.Group("/ex")
|
||||
{
|
||||
ex.GET("/exchangeRates", controllers.GetExchangeRates)
|
||||
ex.Use(middlewares.AuthMiddleWare())
|
||||
ex.POST("/exchangeRates", controllers.CreateExchangeRate)
|
||||
}
|
||||
}
|
||||
}
|
||||
return r
|
||||
|
||||
@@ -2,6 +2,8 @@ package utils
|
||||
|
||||
import (
|
||||
"GinTutorial/config"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
@@ -19,7 +21,7 @@ func GenerateJWT(username string) (string, error) {
|
||||
"exp": time.Now().Add(time.Hour * 72).Unix(),
|
||||
})
|
||||
|
||||
signedToken, err := token.SignedString([]byte("secret"))
|
||||
signedToken, err := token.SignedString([]byte(config.AppConfig.Jwtconfig.Secret))
|
||||
return "Bearer " + signedToken, err
|
||||
}
|
||||
|
||||
@@ -27,3 +29,29 @@ func CheckPassword(password, hash string) bool {
|
||||
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func ParseToken(tokenString string) (string, error) {
|
||||
if len(tokenString) > 7 && tokenString[0:7] == "Bearer " {
|
||||
tokenString = tokenString[7:]
|
||||
}
|
||||
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
|
||||
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
|
||||
}
|
||||
return []byte(config.AppConfig.Jwtconfig.Secret), nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
|
||||
username, ok := claims["username"].(string)
|
||||
if !ok {
|
||||
return "", errors.New("username invalid")
|
||||
}
|
||||
return username, nil
|
||||
}
|
||||
|
||||
return "", errors.New("token invalid")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user