Skip to content

Commit

Permalink
Added refresh token api
Browse files Browse the repository at this point in the history
  • Loading branch information
PfMartin committed Dec 11, 2023
1 parent 562b836 commit bbd24eb
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 2 deletions.
3 changes: 1 addition & 2 deletions api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,13 @@ func (server *Server) SetupRouter() {

router.POST("/users", server.createUser)
router.POST("/users/login", server.loginUser)
router.POST("/token/renew_access", server.renewAccessToken)

authRoutes := router.Group("/").Use(authMiddleware(server.tokenMaker))

authRoutes.POST("/accounts", server.createAccount)
authRoutes.GET("/accounts/:id", server.getAccount)
authRoutes.GET("/accounts", server.listAccount)
// TODO: Update account route
// TODO: Delete account route

authRoutes.POST("/transfers", server.createTransfer)

Expand Down
83 changes: 83 additions & 0 deletions api/token.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package api

import (
"database/sql"
"fmt"
"net/http"
"time"

"github.com/gin-gonic/gin"
)

type renewAccessTokenRequest struct {
RefreshToken string `json:"refresh_token" binding:"required"`
}

type renewAccessTokenResponse struct {
AccessToken string `json:"access_token"`
AccessTokenExpiresAt time.Time `json:"access_token_expires_at"`
}

func (server *Server) renewAccessToken(ctx *gin.Context) {
var req renewAccessTokenRequest
if err := ctx.ShouldBindJSON(&req); err != nil {
ctx.JSON(http.StatusBadRequest, errorResponse(err))
return
}

refreshPayload, err := server.tokenMaker.VerifyToken(req.RefreshToken)
if err != nil {
ctx.JSON(http.StatusUnauthorized, errorResponse(err))
return
}

session, err := server.store.GetSession(ctx, refreshPayload.ID)
if err != nil {
if err == sql.ErrNoRows {
ctx.JSON(http.StatusNotFound, errorResponse(err))
return
}
ctx.JSON(http.StatusInternalServerError, errorResponse(err))
return
}

if session.IsBlocked {
err := fmt.Errorf("blocked session")
ctx.JSON(http.StatusUnauthorized, errorResponse(err))
return
}

if session.Username != refreshPayload.Username {
err := fmt.Errorf("incorrect session user")
ctx.JSON(http.StatusUnauthorized, errorResponse(err))
return
}

if session.RefreshToken != req.RefreshToken {
err := fmt.Errorf("mismatched session token")
ctx.JSON(http.StatusUnauthorized, errorResponse(err))
return
}

if time.Now().After(session.ExpiresAt) {
err := fmt.Errorf("expired session")
ctx.JSON(http.StatusUnauthorized, errorResponse(err))
return
}

accessToken, accessPayload, err := server.tokenMaker.CreateToken(
refreshPayload.Username,
server.config.AccessTokenDuration,
)
if err != nil {
ctx.JSON(http.StatusInternalServerError, errorResponse(err))
return
}

res := renewAccessTokenResponse{
AccessToken: accessToken,
AccessTokenExpiresAt: accessPayload.ExpiredAt,
}
ctx.JSON(http.StatusOK, res)

}

0 comments on commit bbd24eb

Please sign in to comment.