-
Notifications
You must be signed in to change notification settings - Fork 3
/
middleware.go
88 lines (72 loc) · 2.55 KB
/
middleware.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package handlers
import (
"context"
"fmt"
"net/http"
"github.com/dgrijalva/jwt-go"
"github.com/florianwoelki/insta-clone/internal"
)
// MiddlewareValidateAccount checks wether the input is a valid json formatted
// account. When it is it will pass the next http handler
func (a *Accounts) MiddlewareValidateAccount(next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
rw.Header().Add("Content-Type", "application/json")
account := &internal.Account{}
err := internal.FromJSON(account, r.Body)
if err != nil {
a.logger.Println("[ERROR] Deserializing account", err)
http.Error(rw, "Error reading account", http.StatusBadRequest)
return
}
// try to validate the input account
errs := a.validator.Validate(account)
if len(errs) != 0 {
a.logger.Printf("[ERROR] Validating account: %v", errs)
http.Error(rw, fmt.Sprintf("Error validating account %v", errs), http.StatusUnprocessableEntity)
return
}
// add account to context
ctx := context.WithValue(r.Context(), KeyAccount{}, account)
r = r.WithContext(ctx)
next.ServeHTTP(rw, r)
})
}
// MiddlewareValidateToken validates if the jwt in the cookie is valid
func (a *Accounts) MiddlewareValidateToken(next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
rw.Header().Add("Content-Type", "application/json")
c, err := r.Cookie("token")
if err != nil {
if err == http.ErrNoCookie {
a.logger.Printf("[ERROR] Cookie is not set, error %v", err)
http.Error(rw, "Not authorized", http.StatusUnauthorized)
return
}
a.logger.Printf("[ERROR] Something went wrong while fetching the token cookie, error %v", err)
http.Error(rw, "Something internally went wrong", http.StatusBadRequest)
return
}
tokenStr := c.Value
claims := &internal.Claims{}
token, err := jwt.ParseWithClaims(tokenStr, claims, func(token *jwt.Token) (interface{}, error) {
return internal.JWTKey, nil
})
if err != nil {
if err == jwt.ErrSignatureInvalid {
a.logger.Printf("[ERROR] Invalid token, error: %v", err)
http.Error(rw, "Invalid token", http.StatusUnauthorized)
return
}
a.logger.Printf("[ERROR] Something went wrong while validating the token cookie, error: %v", err)
http.Error(rw, "Something went wrong internally", http.StatusBadRequest)
return
}
// check if token is invalid
if !token.Valid {
a.logger.Println("[ERROR] Invalid token")
http.Error(rw, "Invalid token", http.StatusUnauthorized)
return
}
next.ServeHTTP(rw, r)
})
}