Skip to content

Commit

Permalink
Merge pull request #6 from el-Mike/auth/logout-mechanism
Browse files Browse the repository at this point in the history
feat: logout mechanism
  • Loading branch information
el-mike authored Mar 14, 2021
2 parents 44e52c9 + 31b3c48 commit 18380b2
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 0 deletions.
6 changes: 6 additions & 0 deletions auth/auth_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"time"

"github.com/dgrijalva/jwt-go"
"github.com/el-Mike/gochat/common/api"
"github.com/el-Mike/gochat/models"
"github.com/el-Mike/gochat/persist"
"github.com/go-redis/redis/v8"
Expand Down Expand Up @@ -54,6 +55,11 @@ func (am *AuthManager) Login(user *models.UserModel, apiSecret string) (string,
return token, nil
}

// Logout - logs user out by removing it's authorization entry from Redis store.
func (am *AuthManager) Logout(contextUser *api.ContextUser) error {
return am.redis.Del(ctx, contextUser.AuthUUID.String()).Err()
}

// VerifyToken - verifies and parses JWT token.
func (am *AuthManager) VerifyToken(request *http.Request, apiSecret string) (*jwt.Token, error) {
tokenString := am.ExtractToken(request)
Expand Down
13 changes: 13 additions & 0 deletions controllers/auth_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,19 @@ func (ac *AuthController) Login(ctx *gin.Context) {
ctx.JSON(http.StatusOK, loginResponse)
}

// Logout - logs out a user.
func (ac *AuthController) Logout(ctx *gin.Context) {
contextUser := ctx.MustGet(api.ContextUserKey).(*api.ContextUser)

if err := ac.authService.Logout(contextUser); err != nil {
ctx.JSON(api.ResponseFromError(api.NewInternalError(err)))

return
}

ctx.JSON(http.StatusOK, gin.H{"status": "OK"})
}

// SignUp - registers a new user
func (ac *AuthController) SignUp(ctx *gin.Context) {
var credentials schema.SignupPayload
Expand Down
13 changes: 13 additions & 0 deletions middlewares/auth_middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ import (
"github.com/dgrijalva/jwt-go"
"github.com/el-Mike/gochat/auth"
"github.com/el-Mike/gochat/common/api"
"github.com/el-Mike/gochat/persist"
"github.com/gin-gonic/gin"
)

// AuthMiddleware - middleware for authenticating and authorizing the user.
func AuthMiddleware() gin.HandlerFunc {
authManager := auth.NewAuthManager()
redis := persist.RedisClient

return func(ctx *gin.Context) {
request := ctx.Request
Expand Down Expand Up @@ -45,6 +47,17 @@ func AuthMiddleware() gin.HandlerFunc {

return
}

// If there is no authorization entry is Redis store, it means that
// user logged out from the application - therefore token expired,
// even if it's still valid time-wise.
if err := redis.Get(ctx, authUUID.String()).Err(); err != nil {
ctx.JSON(api.ResponseFromError(api.NewTokenExpiredError()))
ctx.Abort()

return
}

email := claims["email"].(string)

currentUser := &api.ContextUser{
Expand Down
3 changes: 3 additions & 0 deletions routing/auth_routing.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package routing

import (
"github.com/el-Mike/gochat/controllers"
"github.com/el-Mike/gochat/middlewares"
"github.com/gin-gonic/gin"
)

Expand All @@ -11,4 +12,6 @@ func DefineAuthRoutes(router *gin.RouterGroup) {

router.POST("/signup", authController.SignUp)
router.POST("/login", authController.Login)

router.POST("/logout", middlewares.AuthMiddleware(), authController.Logout)
}
6 changes: 6 additions & 0 deletions services/auth_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"os"

"github.com/el-Mike/gochat/auth"
"github.com/el-Mike/gochat/common/api"
"github.com/el-Mike/gochat/models"
"github.com/el-Mike/gochat/persist"
"github.com/el-Mike/gochat/schema"
Expand Down Expand Up @@ -42,6 +43,11 @@ func (as *AuthService) Login(user *models.UserModel) (string, error) {
return token, nil
}

// Logout - logs out a user.
func (as *AuthService) Logout(userContext *api.ContextUser) error {
return as.authManager.Logout(userContext)
}

// SignUp - registers a new user, and saves it to DB.
func (as *AuthService) SignUp(credentials schema.SignupPayload) (*models.UserModel, error) {
hashedPassword, err := as.authManager.HashAndSalt([]byte(credentials.Password))
Expand Down

0 comments on commit 18380b2

Please sign in to comment.