make sure that the jwt encryption key is configurable by the end user.
This commit is contained in:
parent
129d728d34
commit
edd8587ab2
|
@ -6,9 +6,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
//TODO: this key should be dynamically generated/taken from config file.
|
|
||||||
var jwtKey = []byte("supersecretkey")
|
|
||||||
|
|
||||||
//TODO: this should match the ID and username for the user.
|
//TODO: this should match the ID and username for the user.
|
||||||
type JWTClaim struct {
|
type JWTClaim struct {
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
|
@ -16,7 +13,7 @@ type JWTClaim struct {
|
||||||
jwt.StandardClaims
|
jwt.StandardClaims
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenerateJWT(username string) (tokenString string, err error) {
|
func GenerateJWT(encryptionKey string, username string) (tokenString string, err error) {
|
||||||
expirationTime := time.Now().Add(2 * time.Hour)
|
expirationTime := time.Now().Add(2 * time.Hour)
|
||||||
claims := &JWTClaim{
|
claims := &JWTClaim{
|
||||||
Username: username,
|
Username: username,
|
||||||
|
@ -26,11 +23,11 @@ func GenerateJWT(username string) (tokenString string, err error) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||||
tokenString, err = token.SignedString(jwtKey)
|
tokenString, err = token.SignedString([]byte(encryptionKey))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func ValidateToken(signedToken string) (*JWTClaim, error) {
|
func ValidateToken(encryptionKey string, signedToken string) (*JWTClaim, error) {
|
||||||
token, err := jwt.ParseWithClaims(
|
token, err := jwt.ParseWithClaims(
|
||||||
signedToken,
|
signedToken,
|
||||||
&JWTClaim{},
|
&JWTClaim{},
|
||||||
|
@ -38,7 +35,7 @@ func ValidateToken(signedToken string) (*JWTClaim, error) {
|
||||||
if jwt.SigningMethodHS256 != token.Method {
|
if jwt.SigningMethodHS256 != token.Method {
|
||||||
return nil, errors.New("Invalid signing algorithm")
|
return nil, errors.New("Invalid signing algorithm")
|
||||||
}
|
}
|
||||||
return []byte(jwtKey), nil
|
return []byte(encryptionKey), nil
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -3,6 +3,7 @@ package handler
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg/auth"
|
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg/auth"
|
||||||
|
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg/config"
|
||||||
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg/database"
|
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg/database"
|
||||||
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg/models"
|
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg/models"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
@ -11,6 +12,7 @@ import (
|
||||||
|
|
||||||
func AuthSignup(c *gin.Context) {
|
func AuthSignup(c *gin.Context) {
|
||||||
databaseRepo := c.MustGet("REPOSITORY").(database.DatabaseRepository)
|
databaseRepo := c.MustGet("REPOSITORY").(database.DatabaseRepository)
|
||||||
|
appConfig := c.MustGet("CONFIG").(config.Interface)
|
||||||
|
|
||||||
var user models.User
|
var user models.User
|
||||||
if err := c.ShouldBindJSON(&user); err != nil {
|
if err := c.ShouldBindJSON(&user); err != nil {
|
||||||
|
@ -24,7 +26,7 @@ func AuthSignup(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// return JWT
|
// return JWT
|
||||||
tokenString, err := auth.GenerateJWT(user.Username)
|
tokenString, err := auth.GenerateJWT(appConfig.GetString("web.jwt.encryptionKey"), user.Username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusInternalServerError, gin.H{"success": false})
|
c.JSON(http.StatusInternalServerError, gin.H{"success": false})
|
||||||
return
|
return
|
||||||
|
@ -35,6 +37,7 @@ func AuthSignup(c *gin.Context) {
|
||||||
|
|
||||||
func AuthSignin(c *gin.Context) {
|
func AuthSignin(c *gin.Context) {
|
||||||
databaseRepo := c.MustGet("REPOSITORY").(database.DatabaseRepository)
|
databaseRepo := c.MustGet("REPOSITORY").(database.DatabaseRepository)
|
||||||
|
appConfig := c.MustGet("CONFIG").(config.Interface)
|
||||||
|
|
||||||
var user models.User
|
var user models.User
|
||||||
if err := c.ShouldBindJSON(&user); err != nil {
|
if err := c.ShouldBindJSON(&user); err != nil {
|
||||||
|
@ -55,7 +58,7 @@ func AuthSignin(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// return JWT
|
// return JWT
|
||||||
tokenString, err := auth.GenerateJWT(user.Username)
|
tokenString, err := auth.GenerateJWT(appConfig.GetString("web.jwt.encryptionKey"), user.Username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "error": "an error occurred generating JWT token"})
|
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "error": "an error occurred generating JWT token"})
|
||||||
return
|
return
|
||||||
|
|
|
@ -2,6 +2,7 @@ package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg/auth"
|
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg/auth"
|
||||||
|
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg/config"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -10,6 +11,8 @@ import (
|
||||||
|
|
||||||
func RequireAuth() gin.HandlerFunc {
|
func RequireAuth() gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
|
appConfig := c.MustGet("CONFIG").(config.Interface)
|
||||||
|
|
||||||
authHeader := c.GetHeader("Authorization")
|
authHeader := c.GetHeader("Authorization")
|
||||||
authHeaderParts := strings.Split(authHeader, " ")
|
authHeaderParts := strings.Split(authHeader, " ")
|
||||||
|
|
||||||
|
@ -27,13 +30,14 @@ func RequireAuth() gin.HandlerFunc {
|
||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
claim, err := auth.ValidateToken(tokenString)
|
claim, err := auth.ValidateToken(appConfig.GetString("web.jwt.encryptionKey"), tokenString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusUnauthorized, gin.H{"success": false, "error": err.Error()})
|
c.JSON(http.StatusUnauthorized, gin.H{"success": false, "error": err.Error()})
|
||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//todo, is this shared between all sessions??
|
||||||
c.Set("AUTH_TOKEN", tokenString)
|
c.Set("AUTH_TOKEN", tokenString)
|
||||||
c.Set("AUTH_USERNAME", claim.Username)
|
c.Set("AUTH_USERNAME", claim.Username)
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
version: 1
|
version: 1
|
||||||
|
|
||||||
web:
|
web:
|
||||||
|
jwt:
|
||||||
|
# used to encrypt/validate JWT session key (used for authentication)
|
||||||
|
encryptionKey: 'changethissupersecretkey'
|
||||||
listen:
|
listen:
|
||||||
port: 9090
|
port: 9090
|
||||||
host: 0.0.0.0
|
host: 0.0.0.0
|
||||||
|
|
Loading…
Reference in New Issue