auth/auth.go (view raw)
1package auth
2
3import (
4 "crypto/rand"
5 "encoding/hex"
6 "net/http"
7 "time"
8
9 "golang.org/x/crypto/bcrypt"
10)
11
12type Auth struct {
13 Pepper string
14}
15
16func NewAuth(pepper string) *Auth {
17 return &Auth{
18 Pepper: pepper,
19 }
20}
21
22func (g Auth) HashPassword(password string) (hashedPassword, salt string, err error) {
23 salt, err = g.GenerateRandomToken(16)
24 if err != nil {
25 return
26 }
27
28 bytesPassword, err := bcrypt.GenerateFromPassword([]byte(password+salt+g.Pepper), bcrypt.DefaultCost)
29 if err != nil {
30 return
31 }
32 hashedPassword = string(bytesPassword)
33 return
34}
35
36func (g Auth) CheckPassword(password, salt, hash string) bool {
37 return bcrypt.CompareHashAndPassword([]byte(hash), []byte(password+salt+g.Pepper)) == nil
38}
39
40func (g Auth) GenerateRandomToken(n int) (string, error) {
41 token := make([]byte, n)
42 _, err := rand.Read(token)
43 if err != nil {
44 return "", err
45 }
46 return hex.EncodeToString(token), nil
47}
48
49func (g Auth) GenerateCookie(duration time.Duration) (*http.Cookie, error) {
50 sessionToken, err := g.GenerateRandomToken(32)
51 if err != nil {
52 return nil, err
53 }
54
55 return &http.Cookie{
56 Name: "session_token",
57 Value: sessionToken,
58 Expires: time.Now().Add(duration),
59 Path: "/",
60 HttpOnly: true,
61 Secure: true,
62 }, nil
63}
64
65func (g Auth) GenerateEmptyCookie() *http.Cookie {
66 return &http.Cookie{
67 Name: "session_token",
68 Value: "",
69 Expires: time.Now().Add(-1 * time.Hour),
70 Path: "/",
71 }
72}