The server for Open Course World
at main 98 lines 2.5 kB view raw
1package api 2 3import ( 4 "context" 5 "fmt" 6 "net/http" 7 "smm2_gameserver/orm" 8 "strconv" 9 "time" 10 11 "github.com/dgrijalva/jwt-go" 12) 13 14// Define a function to create a new JWT token 15func createToken(userID orm.BigInt) (string, error) { 16 // Create the claims for the token 17 claims := jwt.MapClaims{ 18 "sub": userID, 19 "exp": time.Now().Add(time.Hour * 24 * 14).Unix(), // Token will expire in 2 weeks 20 } 21 22 // Create the token object with claims and sign it with the secret key 23 token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) 24 signedToken, err := token.SignedString(jwtSecret) 25 if err != nil { 26 return "", err 27 } 28 29 return signedToken, nil 30} 31 32func JwtMiddleware(next http.Handler) http.Handler { 33 return jwtMiddleware(next) 34} 35 36func readAuthHeaders(r *http.Request) (*http.Request, error) { 37 // Get the token from the Authorization header 38 authHeader := r.Header.Get("Authorization") 39 if authHeader == "" { 40 return nil, fmt.Errorf("empty auth header") 41 } 42 43 // Parse the token and verify it with the secret key 44 tokenString := authHeader[len("Bearer "):] 45 token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { 46 if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { 47 return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) 48 } 49 return jwtSecret, nil 50 }) 51 52 if err != nil { 53 return nil, err 54 } 55 56 claims, ok := token.Claims.(jwt.MapClaims) 57 58 if !ok || !token.Valid { 59 return nil, fmt.Errorf("invalid token") 60 } 61 62 // Extract the userID from the token claims and set it in the request context 63 userID, err := strconv.ParseInt(claims["sub"].(string), 10, 64) 64 if err != nil { 65 return nil, fmt.Errorf("invalid format for user id") 66 } 67 68 ctx := context.WithValue(r.Context(), "userID", userID) 69 70 return r.WithContext(ctx), nil 71} 72 73// Define a middleware function to verify the JWT token and set the user in the request context 74func jwtMiddleware(next http.Handler) http.Handler { 75 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 76 newReq, err := readAuthHeaders(r) 77 78 if err != nil { 79 http.Error(w, "Unauthorized", http.StatusUnauthorized) 80 return 81 } 82 83 next.ServeHTTP(w, newReq) 84 }) 85} 86 87func getUserId(r *http.Request) int64 { 88 return r.Context().Value("userID").(int64) 89} 90 91// // Define a handler function that requires a valid JWT token to be present 92// func myHandler(w http.ResponseWriter, r *http.Request) { 93// // Get the userID from the request context 94// userID := r.Context().Value("userID").(string) 95// 96// // Do something with the userID 97// // ... 98// }