-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
138 lines (111 loc) · 3.37 KB
/
main.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package main
import (
"log"
"os"
"strconv"
"time"
"github.com/gofiber/fiber/v2"
"github.com/golang-jwt/jwt/v4"
)
var numberOfAuthorizations int64 = 0
var numberOfVerifications int64 = 0
var sumOfAuthorizationTimes int64 = 0
var sumOfVerificationTimes int64 = 0
func main() {
app := fiber.New()
//auth route
app.Get("/auth/:userName", auth)
//verify route
app.Get("/verify", verify)
//stats route
app.Get("/stats", stats)
//readme route
app.Get("/README.txt", readme)
app.Listen(":80")
}
func fatal(err error) {
if err != nil {
log.Fatal(err)
}
}
func auth(c *fiber.Ctx) error {
startTime := time.Now()
privateBytes, err := os.ReadFile("private.pem")
fatal(err)
publicBytes, err := os.ReadFile("public.pem")
fatal(err)
privateKey, err := jwt.ParseRSAPrivateKeyFromPEM(privateBytes)
fatal(err)
// create new JWT RSA256 Token and add claims to it
token := jwt.New(jwt.SigningMethodRS256)
claims := token.Claims.(jwt.MapClaims)
claims["sub"] = c.Params("userName")
// expiration date of 1 day
claims["exp"] = time.Now().Add(time.Hour * 24).Unix()
tokenString, err := token.SignedString(privateKey)
fatal(err)
// Create jwt cookie
cookie := new(fiber.Cookie)
cookie.Name = "token"
cookie.HTTPOnly = true
cookie.Value = tokenString
// Set cookie
c.Cookie(cookie)
numberOfAuthorizations++
sumOfAuthorizationTimes += time.Since(startTime).Microseconds()
// return public key
return c.SendString(string(publicBytes))
}
func verify(c *fiber.Ctx) error {
startTime := time.Now()
publicBytes, err := os.ReadFile("public.pem")
fatal(err)
publicKey, err := jwt.ParseRSAPublicKeyFromPEM(publicBytes)
fatal(err)
tokenString := c.Cookies("token")
// check if token exists within cookie
if tokenString == "" {
c.Status(400)
return c.SendString("Token not found in cookie")
}
claims := jwt.MapClaims{}
// parse cookie from request and get claims, verify cookie with public key
_, err = jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
return publicKey, nil
})
// if verification fails return 401
if err != nil {
c.Status(401)
return c.SendString("Token is invalid")
}
numberOfVerifications++
sumOfVerificationTimes += time.Since(startTime).Microseconds()
// return userName claim as string
return c.SendString(claims["sub"].(string))
}
func stats(c *fiber.Ctx) error {
var numberOfVerificationsString = "0"
var averageOfVerificationsString = "n/a"
var numberOfAuthorizationsString = "0"
var averageOfAuthorizationsString = "n/a"
// μs are the unit for microseconds
if numberOfVerifications != 0 {
numberOfVerificationsString = strconv.FormatInt(numberOfVerifications, 10)
averageOfVerificationsString = strconv.FormatInt(sumOfVerificationTimes/numberOfVerifications, 10) + "μs"
}
if numberOfAuthorizations != 0 {
numberOfAuthorizationsString = strconv.FormatInt(numberOfAuthorizations, 10)
averageOfAuthorizationsString = strconv.FormatInt(sumOfAuthorizationTimes/numberOfAuthorizations, 10) + "μs"
}
return c.JSON(fiber.Map{
"numberOfVerifications": numberOfVerificationsString,
"averageOfVerifications": averageOfVerificationsString,
"numberOfAuthorizations": numberOfAuthorizationsString,
"averageOfAuthorizations": averageOfAuthorizationsString,
})
}
func readme(c *fiber.Ctx) error {
readmeBytes, err := os.ReadFile("README.txt")
fatal(err)
return c.SendString(string(readmeBytes))
}