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 (
|
import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
|
"main/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Server serves HTTP requests for our banking service.
|
// Server serves HTTP requests for our banking service.
|
||||||
type Server struct {
|
type Server struct {
|
||||||
store *sqlx.DB
|
store *sqlx.DB
|
||||||
router *gin.Engine
|
tokenMaker token.Maker
|
||||||
|
router *gin.Engine
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServer(store *sqlx.DB) (*Server, error) {
|
func NewServer(store *sqlx.DB) (*Server, error) {
|
||||||
@ -22,14 +24,17 @@ func NewServer(store *sqlx.DB) (*Server, error) {
|
|||||||
|
|
||||||
func (server *Server) setupRouter() {
|
func (server *Server) setupRouter() {
|
||||||
router := gin.Default()
|
router := gin.Default()
|
||||||
|
// Default routers
|
||||||
|
router.GET("/welcome", server.welcome)
|
||||||
|
router.POST("/login", server.loginUser)
|
||||||
|
|
||||||
router.GET("/guilds", server.listGuilds)
|
// Authentication routers
|
||||||
router.GET("/guilds/:guild_id", server.getGuild)
|
authRoutes := router.Group("/").Use(authMiddleware(server.tokenMaker))
|
||||||
router.POST("/guilds", server.createGuild)
|
|
||||||
router.DELETE("/guilds/:guild_id", server.deleteGuild)
|
|
||||||
|
|
||||||
authRoutes := router.Group("/")
|
|
||||||
authRoutes.GET("/accounts", server.listAccounts)
|
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
|
server.router = router
|
||||||
}
|
}
|
||||||
|
@ -63,8 +63,12 @@ type Account struct {
|
|||||||
Currency string `json:"currency"`
|
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) {
|
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