feat: add auth middleware, and update event post to make use of it
parent
fce349a31d
commit
73bc1972c7
|
|
@ -17,3 +17,5 @@ content-type: application/json
|
||||||
"email": "test@example.com",
|
"email": "test@example.com",
|
||||||
"password": "examplePassword"
|
"password": "examplePassword"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
> {% client.global.set("auth_token", response.body.jwt); %}
|
||||||
|
|
@ -5,6 +5,7 @@ GET http://localhost:8080/events
|
||||||
### Post a new event
|
### Post a new event
|
||||||
POST http://localhost:8080/events/
|
POST http://localhost:8080/events/
|
||||||
content-type: application/json
|
content-type: application/json
|
||||||
|
Authorization: Bearer {{auth_token}}
|
||||||
|
|
||||||
{
|
{
|
||||||
"name": "My test event",
|
"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
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/golang-jwt/jwt/v5"
|
"github.com/golang-jwt/jwt/v5"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
|
@ -35,6 +36,28 @@ func FindOneByEmail(email string) (*User, error) {
|
||||||
selectQuery := `SELECT * FROM users WHERE email = ?`
|
selectQuery := `SELECT * FROM users WHERE email = ?`
|
||||||
|
|
||||||
dbResponse, err := db.Conn.Query(selectQuery, 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 {
|
if err != nil {
|
||||||
fmt.Println("Something went wrong trying to find a user")
|
fmt.Println("Something went wrong trying to find a user")
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -68,3 +91,9 @@ func (u *User) GetJWToken() (string, error) {
|
||||||
}
|
}
|
||||||
return tokenString, nil
|
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
|
return
|
||||||
}
|
}
|
||||||
// Todo: implement user auth
|
// Todo: implement user auth
|
||||||
event.UserID = 0
|
user, _ := c.Get("user")
|
||||||
|
event.UserID = user.(*models.User).ID
|
||||||
err = event.Save()
|
err = event.Save()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,15 @@
|
||||||
package routes
|
package routes
|
||||||
|
|
||||||
import "github.com/gin-gonic/gin"
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"udemy_httpserver/middleware"
|
||||||
|
)
|
||||||
|
|
||||||
func RegisterRoutes(router *gin.Engine) {
|
func RegisterRoutes(router *gin.Engine) {
|
||||||
router.POST("/events", postEvent)
|
router.POST("/events", middleware.RequireAuth, postEvent)
|
||||||
router.GET("/events", getEvents)
|
router.GET("/events", getEvents)
|
||||||
router.GET("/events/:id", getSingleEvent)
|
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/register", registerUser)
|
||||||
router.POST("/auth/login", Login)
|
router.POST("/auth/login", Login)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue