feat: add auth middleware, and update event post to make use of it
parent
fce349a31d
commit
73bc1972c7
|
|
@ -16,4 +16,6 @@ content-type: application/json
|
|||
{
|
||||
"email": "test@example.com",
|
||||
"password": "examplePassword"
|
||||
}
|
||||
}
|
||||
|
||||
> {% client.global.set("auth_token", response.body.jwt); %}
|
||||
|
|
@ -5,6 +5,7 @@ GET http://localhost:8080/events
|
|||
### Post a new event
|
||||
POST http://localhost:8080/events/
|
||||
content-type: application/json
|
||||
Authorization: Bearer {{auth_token}}
|
||||
|
||||
{
|
||||
"name": "My test event",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"dev": {
|
||||
"name": "value",
|
||||
"auth_token": ""
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
"udemy_httpserver/models"
|
||||
)
|
||||
|
||||
func RequireAuth(c *gin.Context) {
|
||||
// Get JWT from cookie
|
||||
tokenString := c.GetHeader("Authorization")
|
||||
if tokenString == "" {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
tokenString = tokenString[7:] // Remove "Bearer " from the token
|
||||
// Decode/validate it
|
||||
token, _ := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
|
||||
// Don't forget to validate the alg is what you expect:
|
||||
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
|
||||
}
|
||||
|
||||
// hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key")
|
||||
return []byte(os.Getenv("JWT_SECRET")), nil
|
||||
})
|
||||
|
||||
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
|
||||
// Check the expiry date
|
||||
if float64(time.Now().Unix()) > claims["exp"].(float64) {
|
||||
c.AbortWithStatus(http.StatusUnauthorized)
|
||||
}
|
||||
// Validate that the user exists in the database
|
||||
user, err := models.FindOneByID(int(claims["sub"].(float64)))
|
||||
if err != nil || user == nil {
|
||||
c.AbortWithStatus(http.StatusUnauthorized)
|
||||
}
|
||||
c.Set("user", user)
|
||||
c.Next()
|
||||
} else {
|
||||
c.AbortWithStatus(http.StatusUnauthorized)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
|
|
@ -35,6 +36,28 @@ func FindOneByEmail(email string) (*User, error) {
|
|||
selectQuery := `SELECT * FROM users WHERE email = ?`
|
||||
|
||||
dbResponse, err := db.Conn.Query(selectQuery, email)
|
||||
defer closeDbConnection(dbResponse)
|
||||
if err != nil {
|
||||
fmt.Println("Something went wrong trying to find a user")
|
||||
return nil, err
|
||||
}
|
||||
if dbResponse.Next() {
|
||||
var user User
|
||||
err = dbResponse.Scan(&user.ID, &user.Name, &user.Email, &user.Password)
|
||||
if err != nil {
|
||||
fmt.Println("Something went wrong parsing the database row")
|
||||
return nil, err
|
||||
}
|
||||
return &user, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func FindOneByID(id int) (*User, error) {
|
||||
selectQuery := `SELECT * FROM users WHERE id =?`
|
||||
|
||||
dbResponse, err := db.Conn.Query(selectQuery, id)
|
||||
defer closeDbConnection(dbResponse)
|
||||
if err != nil {
|
||||
fmt.Println("Something went wrong trying to find a user")
|
||||
return nil, err
|
||||
|
|
@ -68,3 +91,9 @@ func (u *User) GetJWToken() (string, error) {
|
|||
}
|
||||
return tokenString, nil
|
||||
}
|
||||
func closeDbConnection(dbResponse *sql.Rows) {
|
||||
err := dbResponse.Close()
|
||||
if err != nil {
|
||||
fmt.Println("Something went wrong closing the database row")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ func postEvent(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
// Todo: implement user auth
|
||||
event.UserID = 0
|
||||
user, _ := c.Get("user")
|
||||
event.UserID = user.(*models.User).ID
|
||||
err = event.Save()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
|
|
|
|||
|
|
@ -1,12 +1,15 @@
|
|||
package routes
|
||||
|
||||
import "github.com/gin-gonic/gin"
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"udemy_httpserver/middleware"
|
||||
)
|
||||
|
||||
func RegisterRoutes(router *gin.Engine) {
|
||||
router.POST("/events", postEvent)
|
||||
router.POST("/events", middleware.RequireAuth, postEvent)
|
||||
router.GET("/events", getEvents)
|
||||
router.GET("/events/:id", getSingleEvent)
|
||||
router.PUT("/events/:id", updateEvent)
|
||||
router.PUT("/events/:id", middleware.RequireAuth, updateEvent)
|
||||
|
||||
router.POST("/auth/register", registerUser)
|
||||
router.POST("/auth/login", Login)
|
||||
|
|
|
|||
Loading…
Reference in New Issue