Created
November 11, 2017 14:10
-
-
Save merin83/4c6c6f5826ee98661d2b15fabf2dd1b8 to your computer and use it in GitHub Desktop.
jwt.go
This file contains hidden or 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 ( | |
| "bytes" | |
| "log" | |
| "context" | |
| "fmt" | |
| "net/http" | |
| "time" | |
| "encoding/json" | |
| "github.com/dgrijalva/jwt-go" | |
| "github.com/rs/cors" | |
| ) | |
| type Key int | |
| const MyKey Key = 0 | |
| // JWT schema of the data it will store | |
| type Claims struct { | |
| Username string `json:"username"` | |
| jwt.StandardClaims | |
| } | |
| // type Todo struct { | |
| // Name string | |
| // Completed bool | |
| // Due time.Time | |
| // } | |
| // type Todos []Todo | |
| // log function | |
| var ( | |
| buf bytes.Buffer | |
| logger = log.New(&buf, "INFO: ", log.Lshortfile) | |
| infof = func(info string) { | |
| logger.Output(2, info) | |
| } | |
| ) | |
| // log example just change hello world to your desired log it will add file and line details | |
| // infof("Hello world") | |
| // fmt.Print(&buf) | |
| // to print a value in the terminal | |
| // fmt.Println("Hello world") | |
| // create a JWT and put in the clients cookie | |
| func setToken(res http.ResponseWriter, req *http.Request) { | |
| expireToken := time.Now().Add(time.Hour * 1).UnixNano() / int64(time.Millisecond) | |
| expireCookie := time.Now().Add(time.Hour * 1) | |
| claims := Claims{ | |
| "myusername", | |
| jwt.StandardClaims{ | |
| ExpiresAt: expireToken, | |
| }, | |
| } | |
| token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) | |
| signedToken, _ := token.SignedString([]byte("secret")) | |
| cookie := http.Cookie{Name: "Auth", Value: signedToken, Expires: expireCookie, HttpOnly: true} | |
| http.SetCookie(res, &cookie) | |
| //http.Redirect(res, req, "/profile", 307) | |
| //fmt.Println((json.NewEncoder(res).Encode({token: signedToken}))) | |
| //res.Header().Set("Content-Type", "application/json") | |
| // res.Header().Set("Access-Control-Allow-Origin", "*") | |
| // fmt.Fprintf(res, signedToken) | |
| //myToken := `token: "signedToken"` | |
| // todos := Todos{ | |
| // Todo{Name: "Write presentation"}, | |
| // Todo{Name: "Host meetup"}, | |
| // } | |
| //fmt.Println(res, "Todo show:", signedToken) | |
| //fmt.Fprintln(res, "Todo show:", todos) | |
| //var myToken map[string] string | |
| myToken := make(map[string]string) | |
| myToken["token"] = signedToken; | |
| //myToken := `{token: signedToken}` | |
| // fmt.Println(myToken) | |
| json.NewEncoder(res).Encode(myToken) | |
| //res.Write([]byte(`{"token": signedToken}`)) | |
| } | |
| // middleware to protect private pages | |
| func validate(page http.HandlerFunc) http.HandlerFunc { | |
| return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { | |
| cookie, err := req.Cookie("Auth") | |
| if err != nil { | |
| http.NotFound(res, req) | |
| return | |
| } | |
| token, err := jwt.ParseWithClaims(cookie.Value, &Claims{}, func(token *jwt.Token) (interface{}, error) { | |
| if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { | |
| return nil, fmt.Errorf("Unexpected signing method") | |
| } | |
| return []byte("secret"), nil | |
| }) | |
| if err != nil { | |
| http.NotFound(res, req) | |
| return | |
| } | |
| if claims, ok := token.Claims.(*Claims); ok && token.Valid { | |
| ctx := context.WithValue(req.Context(), MyKey, *claims) | |
| page(res, req.WithContext(ctx)) | |
| } else { | |
| http.NotFound(res, req) | |
| return | |
| } | |
| }) | |
| } | |
| // only viewable if the client has a valid token | |
| func protectedProfile(res http.ResponseWriter, req *http.Request) { | |
| claims, ok := req.Context().Value(MyKey).(Claims) | |
| if !ok { | |
| http.NotFound(res, req) | |
| return | |
| } | |
| fmt.Fprintf(res, "Hello %s", claims.Username) | |
| } | |
| // deletes the cookie | |
| func logout(res http.ResponseWriter, req *http.Request) { | |
| deleteCookie := http.Cookie{Name: "Auth", Value: "none", Expires: time.Now()} | |
| http.SetCookie(res, &deleteCookie) | |
| return | |
| } | |
| func main() { | |
| mux := http.NewServeMux() | |
| handler := cors.Default().Handler(mux) | |
| mux.HandleFunc("/login", setToken) | |
| mux.HandleFunc("/profile", validate(protectedProfile)) | |
| mux.HandleFunc("/logout", validate(logout)) | |
| http.ListenAndServe(":5000", handler) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment