1 package jwt_test
2
3
4
5
6 import (
7 "bytes"
8 "crypto/rsa"
9 "fmt"
10 "io"
11 "io/ioutil"
12 "log"
13 "net"
14 "net/http"
15 "net/url"
16 "strings"
17 "time"
18
19 "github.com/golang-jwt/jwt"
20 "github.com/golang-jwt/jwt/request"
21 )
22
23
24 const (
25 privKeyPath = "test/sample_key"
26 pubKeyPath = "test/sample_key.pub"
27 )
28
29 var (
30 verifyKey *rsa.PublicKey
31 signKey *rsa.PrivateKey
32 serverPort int
33
34
35 users = map[string]string{
36 "test": "known",
37 }
38 )
39
40
41 func init() {
42 signBytes, err := ioutil.ReadFile(privKeyPath)
43 fatal(err)
44
45 signKey, err = jwt.ParseRSAPrivateKeyFromPEM(signBytes)
46 fatal(err)
47
48 verifyBytes, err := ioutil.ReadFile(pubKeyPath)
49 fatal(err)
50
51 verifyKey, err = jwt.ParseRSAPublicKeyFromPEM(verifyBytes)
52 fatal(err)
53
54 http.HandleFunc("/authenticate", authHandler)
55 http.HandleFunc("/restricted", restrictedHandler)
56
57
58 listener, err := net.ListenTCP("tcp", &net.TCPAddr{})
59 fatal(err)
60 serverPort = listener.Addr().(*net.TCPAddr).Port
61
62 log.Println("Listening...")
63 go func() {
64 fatal(http.Serve(listener, nil))
65 }()
66 }
67
68 var start func()
69
70 func fatal(err error) {
71 if err != nil {
72 log.Fatal(err)
73 }
74 }
75
76
77 type CustomerInfo struct {
78 Name string
79 Kind string
80 }
81
82 type CustomClaimsExample struct {
83 *jwt.StandardClaims
84 TokenType string
85 CustomerInfo
86 }
87
88 func Example_getTokenViaHTTP() {
89
90 res, err := http.PostForm(fmt.Sprintf("http://localhost:%v/authenticate", serverPort), url.Values{
91 "user": {"test"},
92 "pass": {"known"},
93 })
94 if err != nil {
95 fatal(err)
96 }
97
98 if res.StatusCode != 200 {
99 fmt.Println("Unexpected status code", res.StatusCode)
100 }
101
102
103 buf := new(bytes.Buffer)
104 io.Copy(buf, res.Body)
105 res.Body.Close()
106 tokenString := strings.TrimSpace(buf.String())
107
108
109 token, err := jwt.ParseWithClaims(tokenString, &CustomClaimsExample{}, func(token *jwt.Token) (interface{}, error) {
110
111
112 return verifyKey, nil
113 })
114 fatal(err)
115
116 claims := token.Claims.(*CustomClaimsExample)
117 fmt.Println(claims.CustomerInfo.Name)
118
119
120 }
121
122 func Example_useTokenViaHTTP() {
123
124
125
126
127 token, err := createToken("foo")
128 fatal(err)
129
130
131 req, err := http.NewRequest("GET", fmt.Sprintf("http://localhost:%v/restricted", serverPort), nil)
132 fatal(err)
133 req.Header.Set("Authorization", fmt.Sprintf("Bearer %v", token))
134 res, err := http.DefaultClient.Do(req)
135 fatal(err)
136
137
138 buf := new(bytes.Buffer)
139 io.Copy(buf, res.Body)
140 res.Body.Close()
141 fmt.Println(buf.String())
142
143
144 }
145
146 func createToken(user string) (string, error) {
147
148 t := jwt.New(jwt.GetSigningMethod("RS256"))
149
150
151 t.Claims = &CustomClaimsExample{
152 &jwt.StandardClaims{
153
154
155 ExpiresAt: time.Now().Add(time.Minute * 1).Unix(),
156 },
157 "level1",
158 CustomerInfo{user, "human"},
159 }
160
161
162 return t.SignedString(signKey)
163 }
164
165
166 func authHandler(w http.ResponseWriter, r *http.Request) {
167
168 if r.Method != "POST" {
169 w.WriteHeader(http.StatusBadRequest)
170 fmt.Fprintln(w, "No POST", r.Method)
171 return
172 }
173
174 user := r.FormValue("user")
175 pass := r.FormValue("pass")
176
177 log.Printf("Authenticate: user[%s] pass[%s]\n", user, pass)
178
179
180 if user != "test" || pass != "known" {
181 w.WriteHeader(http.StatusForbidden)
182 fmt.Fprintln(w, "Wrong info")
183 return
184 }
185
186 tokenString, err := createToken(user)
187 if err != nil {
188 w.WriteHeader(http.StatusInternalServerError)
189 fmt.Fprintln(w, "Sorry, error while Signing Token!")
190 log.Printf("Token Signing error: %v\n", err)
191 return
192 }
193
194 w.Header().Set("Content-Type", "application/jwt")
195 w.WriteHeader(http.StatusOK)
196 fmt.Fprintln(w, tokenString)
197 }
198
199
200 func restrictedHandler(w http.ResponseWriter, r *http.Request) {
201
202 token, err := request.ParseFromRequestWithClaims(r, request.OAuth2Extractor, &CustomClaimsExample{}, func(token *jwt.Token) (interface{}, error) {
203
204
205 return verifyKey, nil
206 })
207
208
209 if err != nil {
210 w.WriteHeader(http.StatusUnauthorized)
211 fmt.Fprintln(w, "Invalid token:", err)
212 return
213 }
214
215
216 fmt.Fprintln(w, "Welcome,", token.Claims.(*CustomClaimsExample).Name)
217 return
218 }
219
View as plain text