add api middleware
This commit is contained in:
parent
9a48d3f673
commit
d00e579458
64
server/adminserver/api/middleware.go
Normal file
64
server/adminserver/api/middleware.go
Normal file
@ -0,0 +1,64 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"main/token"
|
||||
)
|
||||
|
||||
const (
|
||||
authorizationHeaderKey = "authorization"
|
||||
authorizationTypeBearer = "bearer"
|
||||
authorizationTypeBasic = "basic"
|
||||
authorizationPayloadKey = "authorization_payload"
|
||||
)
|
||||
|
||||
func authMiddleware(tokenMaker token.Maker) gin.HandlerFunc {
|
||||
return func(ctx *gin.Context) {
|
||||
authorizationHeader := ctx.GetHeader(authorizationHeaderKey)
|
||||
if len(authorizationHeader) == 0 {
|
||||
err := errors.New("authorization header is not provided")
|
||||
ctx.AbortWithStatusJSON(http.StatusUnauthorized, errorResponse(err))
|
||||
return
|
||||
}
|
||||
|
||||
fields := strings.Fields(authorizationHeader)
|
||||
if len(fields) < 2 {
|
||||
err := errors.New("invalid authorization header format")
|
||||
ctx.AbortWithStatusJSON(http.StatusUnauthorized, errorResponse(err))
|
||||
return
|
||||
}
|
||||
|
||||
// Headers key: Authorization
|
||||
// Headers value: Basic cm9vdDoxMjM0NTY=
|
||||
authorizationType := strings.ToLower(fields[0])
|
||||
if authorizationType == authorizationTypeBasic {
|
||||
|
||||
user, password, hasAuth := ctx.Request.BasicAuth()
|
||||
if hasAuth && user == "root" && password == "123456" {
|
||||
ctx.Next()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if authorizationType != authorizationTypeBearer {
|
||||
err := fmt.Errorf("unsupported authorization type %s", authorizationType)
|
||||
ctx.AbortWithStatusJSON(http.StatusUnauthorized, errorResponse(err))
|
||||
return
|
||||
}
|
||||
|
||||
accessToken := fields[1]
|
||||
payload, err := tokenMaker.VerifyToken(accessToken)
|
||||
if err != nil {
|
||||
ctx.AbortWithStatusJSON(http.StatusUnauthorized, errorResponse(err))
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Set(authorizationPayloadKey, payload)
|
||||
ctx.Next()
|
||||
}
|
||||
}
|
@ -3,12 +3,14 @@ package api
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"main/token"
|
||||
)
|
||||
|
||||
// Server serves HTTP requests for our banking service.
|
||||
type Server struct {
|
||||
store *sqlx.DB
|
||||
router *gin.Engine
|
||||
store *sqlx.DB
|
||||
tokenMaker token.Maker
|
||||
router *gin.Engine
|
||||
}
|
||||
|
||||
func NewServer(store *sqlx.DB) (*Server, error) {
|
||||
@ -22,14 +24,17 @@ func NewServer(store *sqlx.DB) (*Server, error) {
|
||||
|
||||
func (server *Server) setupRouter() {
|
||||
router := gin.Default()
|
||||
// Default routers
|
||||
router.GET("/welcome", server.welcome)
|
||||
router.POST("/login", server.loginUser)
|
||||
|
||||
router.GET("/guilds", server.listGuilds)
|
||||
router.GET("/guilds/:guild_id", server.getGuild)
|
||||
router.POST("/guilds", server.createGuild)
|
||||
router.DELETE("/guilds/:guild_id", server.deleteGuild)
|
||||
|
||||
authRoutes := router.Group("/")
|
||||
// Authentication routers
|
||||
authRoutes := router.Group("/").Use(authMiddleware(server.tokenMaker))
|
||||
authRoutes.GET("/accounts", server.listAccounts)
|
||||
authRoutes.GET("/guilds", server.listGuilds)
|
||||
authRoutes.GET("/guilds/:guild_id", server.getGuild)
|
||||
authRoutes.POST("/guilds", server.createGuild)
|
||||
authRoutes.DELETE("/guilds/:guild_id", server.deleteGuild)
|
||||
|
||||
server.router = router
|
||||
}
|
||||
|
@ -63,8 +63,12 @@ type Account struct {
|
||||
Currency string `json:"currency"`
|
||||
}
|
||||
|
||||
func (server *Server) loginUser(ctx *gin.Context) {
|
||||
func (server *Server) welcome(ctx *gin.Context) {
|
||||
ctx.JSON(http.StatusOK, "welcome")
|
||||
}
|
||||
|
||||
func (server *Server) loginUser(ctx *gin.Context) {
|
||||
ctx.JSON(http.StatusOK, "loginUser")
|
||||
}
|
||||
|
||||
func (server *Server) createAccount(ctx *gin.Context) {
|
||||
|
10
server/adminserver/token/maker.go
Normal file
10
server/adminserver/token/maker.go
Normal file
@ -0,0 +1,10 @@
|
||||
package token
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type Maker interface {
|
||||
CreateToken(username string, duration time.Duration) (string, *Payload, error)
|
||||
VerifyToken(token string) (*Payload, error)
|
||||
}
|
37
server/adminserver/token/payload.go
Normal file
37
server/adminserver/token/payload.go
Normal file
@ -0,0 +1,37 @@
|
||||
package token
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"f5"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrInvalidToken = errors.New("token is invalid")
|
||||
ErrExpiredToken = errors.New("token has expired")
|
||||
)
|
||||
|
||||
type Payload struct {
|
||||
ID int64 `json:"id"`
|
||||
Username string `json:"username"`
|
||||
IssuedAt time.Time `json:"issued_at"`
|
||||
ExpiredAt time.Time `json:"expired_at"`
|
||||
}
|
||||
|
||||
func NewPayload(username string, duration time.Duration) (*Payload, error) {
|
||||
tokenID := f5.GetApp().NewUuid()
|
||||
payload := &Payload{
|
||||
ID: tokenID,
|
||||
Username: username,
|
||||
IssuedAt: time.Now(),
|
||||
ExpiredAt: time.Now().Add(duration),
|
||||
}
|
||||
return payload, nil
|
||||
}
|
||||
|
||||
func (payload *Payload) Valid() error {
|
||||
if time.Now().After(payload.ExpiredAt) {
|
||||
return ErrExpiredToken
|
||||
}
|
||||
return nil
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user