Basic JWT is now working #12
99
api/handlers/v1/auth.go
Normal file
99
api/handlers/v1/auth.go
Normal file
@ -0,0 +1,99 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"go-cook/api/models"
|
||||
"go-cook/api/repositories"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
type JwtToken struct {
|
||||
Exp time.Time `json:"exp"`
|
||||
Authorized bool `json:"authorized"`
|
||||
UserName string `json:"username"`
|
||||
Token string `json:"token"`
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
func generateJwt() (string, error) {
|
||||
//TODO use env here
|
||||
secret := []byte("ThisIsABadSecretDontReallyUseThis")
|
||||
|
||||
token := jwt.New(jwt.SigningMethodEdDSA)
|
||||
claims := token.Claims.(jwt.MapClaims)
|
||||
claims["exp"] = time.Now().Add(10 * time.Minute)
|
||||
claims["authorized"] = true
|
||||
claims["username"] = "someone"
|
||||
|
||||
tokenString, err := token.SignedString(secret)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return tokenString, nil
|
||||
}
|
||||
|
||||
func (h *Handler) AuthRegister(c echo.Context) error {
|
||||
username := c.QueryParam("username")
|
||||
_, err := h.userRepo.GetByName(username)
|
||||
if err != nil {
|
||||
// if we have an err, validate that if its not user not found.
|
||||
// if the user is not found, we can use that name
|
||||
if err.Error() != repositories.ErrUserNotFound {
|
||||
return c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
HttpCode: http.StatusInternalServerError,
|
||||
Message: err.Error(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
password := c.QueryParam("password")
|
||||
err = h.UserService.CheckPasswordForRequirements(password)
|
||||
if err != nil {
|
||||
return c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
HttpCode: http.StatusInternalServerError,
|
||||
Message: err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
_, err = h.userRepo.Create(username, password)
|
||||
if err != nil {
|
||||
return c.JSON(http.StatusInternalServerError, models.ErrorResponse{
|
||||
HttpCode: http.StatusInternalServerError,
|
||||
Message: err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *Handler) AuthLogin(c echo.Context) error {
|
||||
username := c.QueryParam("username")
|
||||
password := c.QueryParam("password")
|
||||
|
||||
// check if the user exists
|
||||
err := h.UserService.DoesUserExist(username)
|
||||
if err != nil {
|
||||
return c.JSON(http.StatusInternalServerError, err)
|
||||
}
|
||||
|
||||
// make sure the hash matches
|
||||
err = h.UserService.DoesPasswordMatchHash(username, password)
|
||||
if err != nil {
|
||||
return c.JSON(http.StatusInternalServerError, err)
|
||||
}
|
||||
|
||||
token, err := generateJwt()
|
||||
if err != nil {
|
||||
return c.JSON(http.StatusInternalServerError, err)
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, token)
|
||||
}
|
||||
|
||||
func (h *Handler) RefreshJwtToken(c echo.Context) error {
|
||||
return nil
|
||||
}
|
@ -47,3 +47,8 @@ func (h *Handler) HelloBody(c echo.Context) error {
|
||||
Message: fmt.Sprintf("Hello, %s", request.Name),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
func (h *Handler) ProtectedRoute(c echo.Context)error {
|
||||
return nil
|
||||
}
|
@ -3,26 +3,52 @@ package v1
|
||||
import (
|
||||
"database/sql"
|
||||
"go-cook/api/repositories"
|
||||
"go-cook/api/services"
|
||||
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
echojwt "github.com/labstack/echo-jwt/v4"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
type Handler struct {
|
||||
userRepo repositories.UserRepository
|
||||
UserService services.UserService
|
||||
userRepo repositories.IUserTable
|
||||
recipeRepo repositories.IRecipeTable
|
||||
}
|
||||
|
||||
func NewHandler(conn *sql.DB) *Handler {
|
||||
return &Handler{
|
||||
userRepo: repositories.NewUserRepository(conn),
|
||||
UserService: services.NewUserService(conn),
|
||||
userRepo: repositories.NewUserRepository(conn),
|
||||
recipeRepo: repositories.NewRecipeRepository(conn),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handler) Register(v1 *echo.Group) {
|
||||
jwtConfig := echojwt.Config{
|
||||
NewClaimsFunc: func(c echo.Context) jwt.Claims {
|
||||
return new(JwtToken)
|
||||
},
|
||||
SigningKey: []byte("ThisIsABadSecretDontReallyUseThis"),
|
||||
}
|
||||
|
||||
v1.POST("/login", h.AuthLogin)
|
||||
v1.POST("/register", h.AuthRegister)
|
||||
demo := v1.Group("/demo")
|
||||
demo.GET("/hello", h.DemoHello)
|
||||
|
||||
demo.GET("/hello", h.DemoHello)
|
||||
demo.GET("/hello/:who", h.HelloWho)
|
||||
|
||||
demo.Use(echojwt.WithConfig(jwtConfig))
|
||||
demo.GET("/hello/body", h.HelloBody)
|
||||
|
||||
users := v1.Group("/users")
|
||||
users.POST("/new", h.NewUser)
|
||||
protected := v1.Group("/demo/protected")
|
||||
protected.GET("/", h.ProtectedRoute)
|
||||
|
||||
//recipes := v1.Group("/recipe")
|
||||
|
||||
//users := v1.Group("/users")
|
||||
//users.POST("/register", h.RegisterUser)
|
||||
//users.POST("/login", h.LoginUser)
|
||||
//users.POST("/update/password", h.UpdatePassword)
|
||||
}
|
||||
|
@ -6,6 +6,10 @@ import (
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
func (h *Handler) NewUser(c echo.Context) error {
|
||||
return c.JSON(http.StatusOK, "not implemented yet")
|
||||
type newUserResponse struct {
|
||||
|
||||
}
|
||||
|
||||
func (h *Handler) RegisterUser(c echo.Context) error {
|
||||
return c.JSON(http.StatusOK, newUserResponse{})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user