/
auth.go
94 lines (83 loc) · 2.32 KB
/
auth.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
89
90
91
92
93
94
package auth
import (
"math/rand"
"net/http"
"time"
"github.com/CoPhi/cophi-auth-service/jwt"
"github.com/CoPhi/cophi-auth-service/refreshtoken"
)
type AuthUser struct {
Email string `json:"email,omitempty"`
Name string `json:"name,omitempty"`
LastName string `json:"lastname,omitempty"`
}
type authHandler struct{ next http.Handler }
func AuthCallback(rts refreshtoken.Store, u *AuthUser, privKey string, domain string, jwtExpiration time.Duration) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
jwtToken, err := jwt.GenerateToken(u.Name, u.LastName, u.Email, jwtExpiration, privKey)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
http.SetCookie(w, &http.Cookie{
Name: "access_token",
Value: jwtToken,
Path: "/",
Domain: domain,
// Secure: true,
})
rt := refreshtoken.New()
rts.Add(rt, u.Email)
http.SetCookie(w, &http.Cookie{
Name: "refresh_token",
Value: rt,
Path: "/",
Domain: domain,
HttpOnly: true,
// Secure: true,
})
referer, err := r.Cookie("referer")
location := "/login"
if err == nil && referer.Value != "" {
location = referer.Value
}
http.SetCookie(w, &http.Cookie{
Name: "referer",
Value: "",
Path: "/",
MaxAge: -1,
HttpOnly: true,
})
w.Header().Set("Location", location) // TODO: make /app redirection parametric to go back to the actual page
w.WriteHeader(http.StatusTemporaryRedirect)
}
}
func invalidCookies(r *http.Request, names ...string) bool {
for _, c := range names {
cookie, err := r.Cookie(c)
if err == http.ErrNoCookie || cookie.Value == "" {
return true
}
}
return false
}
func (h *authHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if invalidCookies(r, "access_token", "refresh_token") {
// not authenticated
w.Header().Set("Location", "/login") // TODO: make login path parametric
w.WriteHeader(http.StatusTemporaryRedirect)
return
}
h.next.ServeHTTP(w, r)
}
func MustAuth(handler http.Handler) http.Handler {
return &authHandler{next: handler}
}
func randomString(n int) string {
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
s := make([]rune, n)
for i := range s {
s[i] = letters[rand.Intn(len(letters))]
}
return string(s)
}