-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtoken_test.go
130 lines (105 loc) · 3.76 KB
/
token_test.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
package jwt_test
import (
"encoding/base64"
"encoding/json"
"strings"
"testing"
"github.com/spiretechnology/go-jwt"
"github.com/stretchr/testify/assert"
)
type testClaims struct {
Name string `json:"name"`
Age int `json:"age"`
}
var (
Secret1 = []byte("0eff92br0ifyg09oji2brpwokweihfbs")
Secret2 = []byte("hgor39rhr02jyrbwpoejriwhbefnxp4g")
)
func TestToken(t *testing.T) {
t.Run("create and parse valid token", func(t *testing.T) {
// Create a new token
token, err := jwt.Create(
testClaims{
Name: "John Smith",
Age: 36,
},
jwt.HS256Signer(Secret1),
)
assert.NoError(t, err, "error creating token")
assert.Equal(t, "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiSm9obiBTbWl0aCIsImFnZSI6MzZ9.kM_p4cZCFlLDjqfTXcriO5J2v9fjomdZP0Ki3Ya0_xg", token, "incorrect signed token string")
// Parse the token
parsed, err := jwt.Parse(token)
assert.NoError(t, err, "error parsing token")
assert.NotNil(t, parsed, "parsed token is nil")
assert.Equal(t, jwt.HS256, parsed.Header().Alg, "incorrect alg in parsed token")
assert.Equal(t, "JWT", parsed.Header().Typ)
// Unmarshal the claims from the token
var claims testClaims
err = parsed.Claims(&claims)
assert.NoError(t, err, "error unmarshalling parsed token claims")
assert.Equal(t, "John Smith", claims.Name)
assert.Equal(t, 36, claims.Age)
// Verify the token
ok, err := parsed.Verify(jwt.HS256Verifier(Secret1))
assert.NoError(t, err, "error verifying token signature")
assert.True(t, ok, "signature verify returned false")
})
t.Run("verify token with incorrect signature", func(t *testing.T) {
// Create a new token
token, _ := jwt.Create(
testClaims{
Name: "John Smith",
Age: 36,
},
jwt.HS256Signer(Secret1),
)
// Parse the token
parsed, err := jwt.Parse(token)
assert.NoError(t, err, "error parsing token")
assert.NotNil(t, parsed, "parsed token is nil")
assert.Equal(t, jwt.HS256, parsed.Header().Alg, "incorrect alg in parsed token")
assert.Equal(t, "JWT", parsed.Header().Typ)
// Verify the token using an invalid secret
ok, err := parsed.Verify(jwt.HS256Verifier(Secret2))
assert.NoError(t, err, "error verifying token signature")
assert.False(t, ok, "signature verify returned true for incorrect secret")
})
t.Run("verify should reject hijacked token", func(t *testing.T) {
// Create a new token
token, _ := jwt.Create(
testClaims{
Name: "John Smith",
Age: 36,
},
jwt.HS256Signer(Secret1),
)
// Edit the claims without re-signing
hijackedToken := spliceClaims(token, testClaims{
Name: "Jimmy Neutron",
Age: 14,
})
// Parse the hijacked token
parsed, err := jwt.Parse(hijackedToken)
assert.NoError(t, err, "error parsing token")
assert.NotNil(t, parsed, "parsed token is nil")
assert.Equal(t, jwt.HS256, parsed.Header().Alg, "incorrect alg in parsed token")
assert.Equal(t, "JWT", parsed.Header().Typ)
// Unmarshal the claims from the hijacked token. The claims should still be unmarshalled
// correctly, even though they were changed by a man-in-the-middle attack.
var claims testClaims
err = parsed.Claims(&claims)
assert.NoError(t, err, "error unmarshalling parsed token claims")
assert.Equal(t, "Jimmy Neutron", claims.Name)
assert.Equal(t, 14, claims.Age)
// Verify the token using an invalid secret. This should fail, even though the secret is the same.
ok, err := parsed.Verify(jwt.HS256Verifier(Secret1))
assert.NoError(t, err, "error verifying token signature")
assert.False(t, ok, "signature verify returned true for hijacked token")
})
}
func spliceClaims(token string, newClaims any) string {
parts := strings.Split(token, ".")
jsonBytes, _ := json.Marshal(newClaims)
parts[1] = base64.RawURLEncoding.EncodeToString(jsonBytes)
return strings.Join(parts, ".")
}