gin_http/routes/auth.routes.go

98 lines
2.4 KiB
Go

package routes
import (
"fmt"
"github.com/gin-gonic/gin"
"golang.org/x/crypto/bcrypt"
"net/http"
"os"
"strings"
"time"
"udemy_httpserver/models"
)
func registerUser(c *gin.Context) {
var user struct {
models.User
PasswordConfirm string `json:"password_confirm"`
}
err := c.ShouldBind(&user)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
candidateUser, err := models.FindOneByEmail(strings.ToLower(user.Email))
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
if candidateUser != nil {
c.JSON(http.StatusConflict, gin.H{"error": fmt.Sprintf("user with email %s already exists", user.Email)})
return
}
if user.Password != user.PasswordConfirm {
c.JSON(http.StatusBadRequest, gin.H{"error": "password_confirm must match password"})
return
}
err = user.New()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
jwt, err := setAuthCookie(c, &user.User)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
user.Password = ""
c.JSON(http.StatusCreated, gin.H{"user": user.User, "token": jwt})
}
func Login(c *gin.Context) {
var loginDTO struct {
Email string `binding:"required" json:"email"`
Password string `binding:"required" json:"password"`
}
err := c.ShouldBind(&loginDTO)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
user, err := models.FindOneByEmail(strings.ToLower(loginDTO.Email))
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(loginDTO.Password))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid password or email"})
return
}
token, err := setAuthCookie(c, user)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"jwt": token})
}
func setAuthCookie(c *gin.Context, user *models.User) (string, error) {
JWToken, err := user.GetJWToken()
expirationDelta, err := time.ParseDuration(os.Getenv("AUTH_EXPIRATION"))
if err != nil {
fmt.Println("Error parsing AUTH_EXPIRATION")
return "", err
}
cookieExpiration := time.Now().Add(expirationDelta).Unix()
c.SetCookie("Authorization", JWToken, int(cookieExpiration), "", "", true, true)
return JWToken, nil
}