Skip to content

Commit

Permalink
finished my full authentication with jwt
Browse files Browse the repository at this point in the history
  • Loading branch information
arturfil committed Jun 29, 2022
1 parent 068932e commit a714596
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 43 deletions.
91 changes: 84 additions & 7 deletions api/handlers.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,46 @@
package main

import (
"chi_soccer/internal/data"
"encoding/json"
"errors"
"net/http"
"os"
"time"

"github.com/golang-jwt/jwt/v4"
)

type jsonResponse struct {
Error bool `json:"error"`
Message string `json:"message"`
Error bool `json:"error"`
Message string `json:"message"`
Data interface{} `json:"data,omitempty"`
}

type responseObj struct {
Message string `json:"message"`
Data interface{} `json:"data,omitempty"`
}

type envelope map[string]interface{}

func (app *application) GetAllUsers(w http.ResponseWriter, r *http.Request) {
var users data.User
all, err := users.GetAll()
if err != nil {
app.errorLog.Println(err)
return
}

app.writeJSON(w, http.StatusOK, envelope{"users": all})
}

func (app *application) Login(w http.ResponseWriter, r *http.Request) {
var myKey = []byte(os.Getenv("SECRET_KEY"))
// key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
// if err != nil {
// log.Fatal(err)
// }
// declare credentials
type credentials struct {
UserName string `json:"email"`
Expand All @@ -27,13 +58,59 @@ func (app *application) Login(w http.ResponseWriter, r *http.Request) {
_ = app.writeJSON(w, http.StatusBadRequest, payload)
}

app.infoLog.Println(creds.UserName, creds.Password)
// send back a response
payload.Error = false
payload.Message = "Signed in"
user, err := app.models.User.GetByEmail(creds.UserName)
if err != nil {
app.errorJSON(w, errors.New("invalid username/password"))
return
}

validPassword, err := user.PasswordMatches(creds.Password)
if err != nil || !validPassword {
app.errorJSON(w, errors.New("invalid username/password"))
return
}

token := jwt.New(jwt.SigningMethodHS256)
claims := token.Claims.(jwt.MapClaims)
claims["authorized"] = true
claims["user"] = user.FirstName
claims["exp"] = time.Now().Add(time.Minute * 60 * 4).Unix()

err = app.writeJSON(w, http.StatusOK, payload)
tokenString, err := token.SignedString(myKey)

if err != nil {
app.errorLog.Println(err)
app.errorJSON(w, err)
return
}

// create response
response := responseObj{
Message: "logged in",
Data: tokenString,
}

// send response if no erros
err = app.writeJSON(w, http.StatusOK, response)
if err != nil {
app.errorLog.Println(err)
}
}

func (app *application) Signup(w http.ResponseWriter, r *http.Request) {
var u data.User
err := json.NewDecoder(r.Body).Decode(&u)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
app.writeJSON(w, http.StatusOK, u)
id, err := app.models.User.Signup(u)
if err != nil {
app.errorLog.Println(err)
app.errorJSON(w, err, http.StatusForbidden)
app.infoLog.Println("Got back if of", id)
newUser, _ := app.models.User.GetById(id)
app.writeJSON(w, http.StatusOK, newUser)
}
}
39 changes: 39 additions & 0 deletions api/middlewares.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package main

import (
"errors"
"fmt"
"net/http"
"os"

"github.com/golang-jwt/jwt/v4"
)

var myKey = []byte(os.Getenv("SECRET_KEY"))

func (app *application) IsAuthorized(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

if r.Header["Authorization"] != nil {
token, err := jwt.Parse(r.Header["Authorization"][0], func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("there was an error")
}
return myKey, nil
})
if err != nil {
payload := jsonResponse{
Error: true,
Message: err.Error(),
}
_ = app.writeJSON(w, http.StatusUnauthorized, payload)
return
}
if token.Valid {
next.ServeHTTP(w, r)
}
} else {
app.errorJSON(w, errors.New("authorization headers missing"))
}
})
}
37 changes: 7 additions & 30 deletions api/routes.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package main

import (
"chi_soccer/internal/data"
"encoding/json"
"fmt"
"net/http"
Expand All @@ -23,18 +22,15 @@ func (app *application) routes() http.Handler {
MaxAge: 300,
}))

// router.Get("/api/users/login", app.Login)
// users login
router.Post("/api/users/login", app.Login)

// users signup
router.Post("/api/users/signup", app.Signup)
// this returns all the users in the db
router.Get("/api/users/all", func(w http.ResponseWriter, r *http.Request) {
var users data.User
all, err := users.GetAll()
if err != nil {
app.errorLog.Println(err)
return
}
app.writeJSON(w, http.StatusOK, all)
router.Route("/api/users/all", func(router chi.Router) {
router.Use(app.IsAuthorized)
router.Get("/", app.GetAllUsers)

})

// route to test if the server is working
Expand All @@ -54,24 +50,5 @@ func (app *application) routes() http.Handler {
app.writeJSON(w, http.StatusOK, &m)
})

// Create a user, this should be a POST method
router.Post("/api/users/signup", func(w http.ResponseWriter, r *http.Request) {
var u data.User
err := json.NewDecoder(r.Body).Decode(&u)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
app.writeJSON(w, http.StatusOK, u)
id, err := app.models.User.Signup(u)
if err != nil {
app.errorLog.Println(err)
app.errorJSON(w, err, http.StatusForbidden)
app.infoLog.Println("Got back if of", id)
newUser, _ := app.models.User.GetById(id)
app.writeJSON(w, http.StatusOK, newUser)
}
})

return router
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
github.com/fsnotify/fsnotify v1.5.4 // indirect
github.com/go-chi/chi/v5 v5.0.7 // indirect
github.com/go-chi/cors v1.2.1 // indirect
github.com/golang-jwt/jwt/v4 v4.4.2 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
github.com/jackc/pgconn v1.12.1 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs=
github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
Expand Down
11 changes: 5 additions & 6 deletions internal/data/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,18 @@ type User struct {
Email string `json:"email"`
FirstName string `json:"first_name,omitempty"`
LastName string `json:"last_name,omitempty"`
Password string `json:"password"`
Password string `json:"-"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Token Token `json:"token"`
Token Token `json:"-"`
}

// this function will return all the users
func (u *User) GetAll() ([]*User, error) {
ctx, cancel := context.WithTimeout(context.Background(), dbTimeout)
defer cancel()

query := `select id, email, first_name, last_name, password, created_at, updated_at from users order by last_name`
query := `select id, email, first_name, last_name, created_at, updated_at from users order by last_name`
rows, err := db.QueryContext(ctx, query)
if err != nil {
return nil, err
Expand All @@ -65,9 +65,8 @@ func (u *User) GetAll() ([]*User, error) {
&user.Email,
&user.FirstName,
&user.LastName,
&user.Password,
&user.CreatedAt,
&user.UpdatedAt,
&user.UpdatedAt,
)
if err != nil {
return nil, err
Expand Down Expand Up @@ -339,7 +338,7 @@ func (t *Token) AuthenticateToken(r *http.Request) (*User, error) {
}

// create token
func (t *Token) InserToken(token Token, u User) error {
func (t *Token) InsertToken(token Token, u User) error {
ctx, cancel := context.WithTimeout(context.Background(), dbTimeout)
defer cancel()

Expand Down
Binary file modified soccerApi
Binary file not shown.

0 comments on commit a714596

Please sign in to comment.