Skip to content

Instantly share code, notes, and snippets.

@merin83
Created November 11, 2017 14:10
Show Gist options
  • Select an option

  • Save merin83/4c6c6f5826ee98661d2b15fabf2dd1b8 to your computer and use it in GitHub Desktop.

Select an option

Save merin83/4c6c6f5826ee98661d2b15fabf2dd1b8 to your computer and use it in GitHub Desktop.
jwt.go
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