-
Notifications
You must be signed in to change notification settings - Fork 0
/
auth.go
131 lines (118 loc) · 3.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
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
package api
import (
"fmt"
"net/http"
"strconv"
"strings"
"time"
"github.com/dgrijalva/jwt-go"
"github.com/gin-gonic/gin"
)
var tokens []string
// jwt secret key
var jwtSecret = []byte("secret")
// custom claims
type Claims struct {
Account string `json:"account"`
Role string `json:"role"`
jwt.StandardClaims
}
// validate JWT
func AuthRequired(context *gin.Context) {
auth := context.GetHeader("Authorization")
token := strings.Split(auth, "Bearer ")[1]
fmt.Println("token: " + token)
// parse and validate token for six things:
// validationErrorMalformed => token is malformed
// validationErrorUnverifiable => token could not be verified because of signing problems
// validationErrorSignatureInvalid => signature validation failed
// validationErrorExpired => exp validation failed
// validationErrorNotValidYet => nbf validation failed
// validationErrorIssuedAt => iat validation failed
tokenClaims, err := jwt.ParseWithClaims(token, &Claims{}, func(token *jwt.Token) (i interface{}, err error) {
return jwtSecret, nil
})
if err != nil {
var message string
if ve, ok := err.(*jwt.ValidationError); ok {
if ve.Errors&jwt.ValidationErrorMalformed != 0 {
message = "token is malformed"
} else if ve.Errors&jwt.ValidationErrorUnverifiable != 0 {
message = "token could not be verified because of signing problems"
} else if ve.Errors&jwt.ValidationErrorSignatureInvalid != 0 {
message = "signature validation failed"
} else if ve.Errors&jwt.ValidationErrorExpired != 0 {
message = "token is expired"
} else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 {
message = "token is not yet valid before sometime"
} else {
message = "can not handle this token"
}
}
context.JSON(http.StatusUnauthorized, gin.H{
"error": message,
})
context.Abort()
return
}
if claims, ok := tokenClaims.Claims.(*Claims); ok && tokenClaims.Valid {
fmt.Println("account:", claims.Account)
fmt.Println("role:", claims.Role)
context.Set("account", claims.Account)
context.Set("role", claims.Role)
context.Next()
} else {
context.Abort()
return
}
}
func GetAuth(context *gin.Context) {
// validate request body
var body struct {
Account string
Password string
}
err := context.ShouldBindJSON(&body)
if err != nil {
context.JSON(http.StatusBadRequest, gin.H{
"error": err.Error(),
})
return
}
// check account and password is correct
if body.Account == "Tomas" && body.Password == "123456" {
now := time.Now()
jwtId := body.Account + strconv.FormatInt(now.Unix(), 10)
role := "Member"
// set claims and sign
claims := Claims{
Account: body.Account,
Role: role,
StandardClaims: jwt.StandardClaims{
Audience: body.Account,
ExpiresAt: now.Add(2000 * time.Second).Unix(),
Id: jwtId,
IssuedAt: now.Unix(),
Issuer: "ginJWT",
NotBefore: now.Add(1 * time.Second).Unix(),
Subject: body.Account,
},
}
tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
token, err := tokenClaims.SignedString(jwtSecret)
if err != nil {
context.JSON(http.StatusInternalServerError, gin.H{
"error": err.Error(),
})
return
}
context.JSON(http.StatusOK, gin.H{
"token": token,
})
return
}
// incorrect account or password
context.JSON(http.StatusUnauthorized, gin.H{
"message": "Unauthorized",
})
}