-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Franco Ferraguti
committed
Oct 5, 2023
1 parent
f483d79
commit cdb3d4d
Showing
23 changed files
with
392 additions
and
194 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,3 +10,6 @@ | |
|
||
# Output of the go coverage tool, specifically when used with LiteIDE | ||
*.out | ||
|
||
# VSCode | ||
.vscode/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package auth | ||
|
||
import ( | ||
"fmt" | ||
"time" | ||
|
||
"github.com/gilperopiola/go-rest-example/pkg/entities" | ||
|
||
"github.com/dgrijalva/jwt-go" | ||
) | ||
|
||
func (auth *Auth) GenerateToken(user entities.User, role AuthRole) string { | ||
|
||
var ( | ||
issuedAt = time.Now().Unix() | ||
expiresAt = time.Now().Add(time.Hour * 24 * time.Duration(auth.sessionDurationDays)).Unix() | ||
) | ||
|
||
claims := &CustomClaims{ | ||
Username: user.Username, | ||
Email: user.Email, | ||
Role: role, | ||
StandardClaims: jwt.StandardClaims{ | ||
Id: fmt.Sprint(user.ID), | ||
Audience: user.Email, | ||
IssuedAt: issuedAt, | ||
ExpiresAt: expiresAt, | ||
}, | ||
} | ||
|
||
// Generate token (struct) | ||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) | ||
|
||
// Generate token (string) | ||
tokenString, _ := token.SignedString([]byte(auth.secret)) | ||
|
||
return tokenString | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package auth | ||
|
||
import ( | ||
"net/http" | ||
"strings" | ||
|
||
"github.com/dgrijalva/jwt-go" | ||
"github.com/gin-gonic/gin" | ||
) | ||
|
||
const ( | ||
UnauthorizedMsg = "unauthorized" | ||
) | ||
|
||
// ValidateToken validates a token for any role and sets ID and Email in context | ||
func (auth *Auth) ValidateToken() gin.HandlerFunc { | ||
return func(c *gin.Context) { | ||
|
||
// Get token first as a string and then as a *jwt.Token | ||
token := auth.getTokenStructFromContext(c) | ||
|
||
// Check if token is valid, then set ID and Email in context | ||
if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid { | ||
c.Set("ID", claims.Id) | ||
c.Set("Email", claims.Audience) | ||
return | ||
} | ||
|
||
c.JSON(http.StatusUnauthorized, UnauthorizedMsg) | ||
c.Abort() | ||
} | ||
} | ||
|
||
// ValidateRole validates a token for a specific role and sets ID and Email in context | ||
func (auth *Auth) ValidateRole(role AuthRole) gin.HandlerFunc { | ||
return func(c *gin.Context) { | ||
|
||
// Get token first as a string and then as a *jwt.Token | ||
token := auth.getTokenStructFromContext(c) | ||
|
||
// Get custom claims from token | ||
customClaims, ok := token.Claims.(*CustomClaims) | ||
|
||
// Check if token is valid, then set ID and Email in context | ||
if ok && token.Valid && customClaims.Role == role { | ||
c.Set("ID", customClaims.Id) | ||
c.Set("Email", customClaims.Audience) | ||
return | ||
} | ||
|
||
c.JSON(http.StatusUnauthorized, UnauthorizedMsg) | ||
c.Abort() | ||
} | ||
} | ||
|
||
func (auth *Auth) getTokenStructFromContext(c *gin.Context) *jwt.Token { | ||
|
||
// Get token string from context | ||
tokenString := removeBearerPrefix(auth.getJWTStringFromHeader(c.Request.Header)) | ||
|
||
// Decode string into actual *jwt.Token | ||
token, err := auth.decodeTokenString(tokenString) | ||
if err == nil { | ||
return token | ||
} | ||
|
||
// Error decoding token | ||
c.JSON(http.StatusUnauthorized, UnauthorizedMsg) | ||
c.Abort() | ||
return nil | ||
} | ||
|
||
// decodeTokenString decodes a JWT token string into a *jwt.Token | ||
func (auth *Auth) decodeTokenString(tokenString string) (*jwt.Token, error) { | ||
|
||
// Check length | ||
if len(tokenString) < 40 { | ||
return &jwt.Token{}, nil | ||
} | ||
|
||
// Make key function | ||
keyFunc := func(token *jwt.Token) (interface{}, error) { return []byte(auth.secret), nil } | ||
|
||
// Parse | ||
return jwt.ParseWithClaims(tokenString, &CustomClaims{}, keyFunc) | ||
} | ||
|
||
func (auth *Auth) getJWTStringFromHeader(header http.Header) string { | ||
return header.Get("Authorization") | ||
} | ||
|
||
func removeBearerPrefix(token string) string { | ||
return strings.TrimPrefix(token, "Bearer ") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.