initial auth route

development
Nilo Roberto C Paim 2023-08-15 14:48:55 -03:00
parent a47d9727ad
commit 4d1884f3a4
7 changed files with 166 additions and 5 deletions

View File

@ -2,7 +2,8 @@ package database
import (
"api/globals"
// "api/models"
"api/models"
// "api/utils"
"fmt"
"log"
@ -42,9 +43,9 @@ func ConnectDB() error {
log.Println("Migrating database tables")
// if result := db.AutoMigrate(&models.User{}); result != nil {
// return result
// }
if result := db.AutoMigrate(&models.User{}); result != nil {
return result
}
// if result := db.AutoMigrate(&models.Event{}); result != nil {
// return result

4
go.mod
View File

@ -3,8 +3,11 @@ module api
go 1.20
require (
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/gofiber/fiber/v2 v2.48.0
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/joho/godotenv v1.5.1
golang.org/x/crypto v0.8.0
gorm.io/driver/postgres v1.5.2
gorm.io/gorm v1.25.3
)
@ -25,7 +28,6 @@ require (
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.48.0 // indirect
github.com/valyala/tcplisten v1.0.0 // indirect
golang.org/x/crypto v0.8.0 // indirect
golang.org/x/sys v0.10.0 // indirect
golang.org/x/text v0.9.0 // indirect
)

4
go.sum
View File

@ -2,8 +2,12 @@ github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/gofiber/fiber/v2 v2.48.0 h1:cRVMCb9aUJDsyHxGFLwz/sGzDggdailZZyptU9F9cU0=
github.com/gofiber/fiber/v2 v2.48.0/go.mod h1:xqJgfqrc23FJuqGOW6DVgi3HyZEm2Mn9pRqUb2kHSX8=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=

9
models/users.go Normal file
View File

@ -0,0 +1,9 @@
package models
type User struct {
Id uint `gorm:"primary key" json:"id"`
Name string `gorm:"size:40;not null" json:"name"`
Email string `gorm:"size:40;not null;unique" json:"email"`
Password []byte `gorm:"size:100;not null;" json:"-"`
UserType string `gorm:"size:1;not null;default:U" json:"usertype"`
}

70
routes/login_route.go Normal file
View File

@ -0,0 +1,70 @@
package routes
import (
"api/models"
"log"
"os"
"strconv"
"time"
"github.com/gofiber/fiber/v2"
"github.com/golang-jwt/jwt/v4"
"golang.org/x/crypto/bcrypt"
)
func Login(c *fiber.Ctx) error {
var data map[string]string
if err := c.BodyParser(&data); err != nil {
log.Printf("Bad Request on parse: %v\n", err)
return fiber.ErrBadRequest
}
var user models.User
if user.Id == 0 {
return c.JSON(fiber.Map{
"message": "Usuário não encontrado",
"userId": 0,
"userType": "",
"userName": "",
"token": ""})
}
if err := bcrypt.CompareHashAndPassword(user.Password, []byte(data["password"])); err != nil {
return c.JSON(fiber.Map{
"message": "Senha inválida",
"userId": 0,
"userType": "",
"userName": "",
"token": ""})
}
type customClaims struct {
Userid string `json:"user"`
jwt.StandardClaims
}
tok := customClaims{
Userid: strconv.Itoa(int(user.Id)),
StandardClaims: jwt.StandardClaims{
Issuer: strconv.Itoa(int(user.Id)),
ExpiresAt: time.Now().Add(time.Hour * 1).Unix(),
},
}
claims := jwt.NewWithClaims(jwt.SigningMethodHS256, tok)
token, err := claims.SignedString([]byte(os.Getenv("API_SECRET")))
if err != nil {
return fiber.ErrInternalServerError
}
return c.JSON(fiber.Map{
"message": "",
"userId": user.Id,
"userType": user.UserType,
"userName": user.Name,
"token": token})
}

View File

@ -6,4 +6,6 @@ func Setup(app *fiber.App) {
app.Get("/", GetVersion)
app.Post("/login", Login)
}

73
utils/utils.go Normal file
View File

@ -0,0 +1,73 @@
package utils
import (
"encoding/json"
"fmt"
"log"
"os"
"strings"
"github.com/dgrijalva/jwt-go"
"github.com/gofiber/fiber/v2"
"golang.org/x/crypto/bcrypt"
)
func HashPassword(password string) ([]byte, error) {
return bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
}
func VerifyAuthentication(c *fiber.Ctx, cookie string) (*jwt.StandardClaims, error) {
token, err := jwt.ParseWithClaims(cookie, &jwt.StandardClaims{}, func(token *jwt.Token) (interface{}, error) {
return []byte(os.Getenv("API_SECRET")), nil
})
if err != nil {
return nil, err
}
claims := token.Claims.(*jwt.StandardClaims)
return claims, nil
}
func ProcessToken(c *fiber.Ctx) (interface{}, error) {
bearToken := c.Get("Authorization")
var token string
// Normally Authorization HTTP header.
onlyToken := strings.Split(bearToken, " ")
if len(onlyToken) == 2 {
token = onlyToken[1]
} else {
token = bearToken
}
tk, err := jwt.Parse(token, jwtKeyFunc)
if err != nil {
fmt.Println("Error 1")
return nil, err
}
claims, ok := tk.Claims.(jwt.MapClaims)
if ok && tk.Valid {
return claims["user"], nil
}
return nil, err
}
func jwtKeyFunc(token *jwt.Token) (interface{}, error) {
return []byte(os.Getenv("API_SECRET")), nil
}
func PrettyPrintJson(data interface{}) {
b, err := json.MarshalIndent(data, "", " ")
if err != nil {
fmt.Println("error:", err)
}
log.Println(string(b))
}