-
-
Save ilmsg/a286a05f1dad386868ac0e79153c5ced to your computer and use it in GitHub Desktop.
JWT tutorial in Go using the golang-jwt package
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/json" | |
"fmt" | |
"github.com/golang-jwt/jwt" | |
"log" | |
"net/http" | |
"time" | |
) | |
type Message struct { | |
Status string `json:"status"` | |
Info string `json:"info"` | |
} | |
var sampleSecretKey = []byte("SecretYouShouldHide") | |
func handlePage(writer http.ResponseWriter, request *http.Request) { | |
_, err := generateJWT() | |
if err != nil { | |
log.Fatalln("Error generating JWT", err) | |
} | |
writer.Header().Set("Token", "%v") | |
type_ := "application/json" | |
writer.Header().Set("Content-Type", type_) | |
var message Message | |
err = json.NewDecoder(request.Body).Decode(&message) | |
if err != nil { | |
return | |
} | |
err = json.NewEncoder(writer).Encode(message) | |
if err != nil { | |
return | |
} | |
} | |
func generateJWT() (string, error) { | |
token := jwt.New(jwt.SigningMethodEdDSA) | |
claims := token.Claims.(jwt.MapClaims) | |
claims["exp"] = time.Now().Add(10 * time.Minute) | |
claims["authorized"] = true | |
claims["user"] = "username" | |
tokenString, err := token.SignedString(sampleSecretKey) | |
if err != nil { | |
return "Signing Error", err | |
} | |
return tokenString, nil | |
} | |
// comment these | |
func verifyJWT(endpointHandler func(writer http.ResponseWriter, request *http.Request)) http.HandlerFunc { | |
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { | |
if request.Header["Token"] != nil { | |
token, err := jwt.Parse(request.Header["Token"][0], func(token *jwt.Token) (interface{}, error) { | |
_, ok := token.Method.(*jwt.SigningMethodECDSA) | |
if !ok { | |
writer.WriteHeader(http.StatusUnauthorized) | |
_, err := writer.Write([]byte("You're Unauthorized")) | |
if err != nil { | |
return nil, err | |
} | |
} | |
return "", nil | |
}) | |
// parsing errors result | |
if err != nil { | |
writer.WriteHeader(http.StatusUnauthorized) | |
_, err2 := writer.Write([]byte("You're Unauthorized due to error parsing the JWT")) | |
if err2 != nil { | |
return | |
} | |
} | |
// if there's a token | |
if token.Valid { | |
endpointHandler(writer, request) | |
} else { | |
writer.WriteHeader(http.StatusUnauthorized) | |
_, err := writer.Write([]byte("You're Unauthorized due to invalid token")) | |
if err != nil { | |
return | |
} | |
} | |
} else { | |
writer.WriteHeader(http.StatusUnauthorized) | |
_, err := writer.Write([]byte("You're Unauthorized due to No token in the header")) | |
if err != nil { | |
return | |
} | |
} | |
// response for if there's no token header | |
}) | |
} | |
func extractClaims(_ http.ResponseWriter, request *http.Request) (string, error) { | |
if request.Header["Token"] != nil { | |
tokenString := request.Header["Token"][0] | |
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { | |
if _, ok := token.Method.(*jwt.SigningMethodECDSA); !ok { | |
return nil, fmt.Errorf("there's an error with the signing method") | |
} | |
return sampleSecretKey, nil | |
}) | |
if err != nil { | |
return "Error Parsing Token: ", err | |
} | |
claims, ok := token.Claims.(jwt.MapClaims) | |
if ok && token.Valid { | |
username := claims["username"].(string) | |
return username, nil | |
} | |
} | |
return "unable to extract claims", nil | |
} | |
func authPage() { | |
token, _ := generateJWT() | |
client := &http.Client{} | |
req, _ := http.NewRequest("GET", "http://localhost:8080/", nil) | |
req.Header.Set("Token", token) | |
_, _ = client.Do(req) | |
} | |
func main() { | |
http.HandleFunc("/home", verifyJWT(handlePage)) | |
err := http.ListenAndServe(":8080", nil) | |
if err != nil { | |
log.Println("There was an error listening on port :8080", err) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment