Skip to content

Instantly share code, notes, and snippets.

@eoinahern
Created April 17, 2022 09:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eoinahern/6ed79ae2dca7e21b159ca21bb38825e2 to your computer and use it in GitHub Desktop.
Save eoinahern/6ed79ae2dca7e21b159ca21bb38825e2 to your computer and use it in GitHub Desktop.
package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
"strings"
"time"
"github.com/golang-jwt/jwt"
"github.com/gorilla/mux"
)
type Payload struct {
Iat string
Username string
}
func (p Payload) Valid() error {
return nil
}
type TimeResponse struct {
Time string `json:"time"`
User string `json:"user"`
}
type TokenResponse struct {
Token string `json:"token"`
Status string `json:"status"`
}
var users map[string]string = map[string]string{"eoinahern": "pass", "jazzhands": "pass1"}
var secretKey string = os.Getenv("SESSION_SECRET")
func handleLogin(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
sendRequest(w, "bad request", http.StatusBadRequest)
return
}
name := r.PostForm.Get("name")
sentPass := r.PostForm.Get("password")
if pass, ok := users[name]; (pass == sentPass) && ok {
token, err := createToken(name)
if err != nil {
sendRequest(w, "server error!", http.StatusInternalServerError)
return
}
bytes, _ := json.Marshal(TokenResponse{
Token: token,
Status: "success",
})
w.Write(bytes)
} else {
sendRequest(w, "please send username with correct pass", http.StatusBadRequest)
return
}
}
func sendRequest(w http.ResponseWriter, msg string, reponsecode int) {
w.WriteHeader(reponsecode)
w.Write([]byte(msg))
}
func createToken(username string) (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"username": username,
"iat": time.Now().Unix(),
})
tokenString, err := token.SignedString([]byte(secretKey))
if err != nil {
return "", err
} else {
return tokenString, nil
}
}
func ExtractToken(tokenIn string) *jwt.Token {
token, _ := jwt.Parse(tokenIn, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v",
token.Header["alg"])
}
return []byte(secretKey), nil
})
return token
}
func extractUserNameFromToken(token *jwt.Token) string {
myMap, ok := token.Claims.(jwt.MapClaims)
if ok {
return myMap["username"].(string)
} else {
return ""
}
}
func checkTokenValid(token *jwt.Token) bool {
_, ok := token.Claims.(jwt.MapClaims)
return token.Valid && ok
}
func healthCheck(w http.ResponseWriter, r *http.Request) {
authData := r.Header.Get("Authorization")
mySlice := strings.Split(authData, "Bearer ")
token := mySlice[1]
actualToken := ExtractToken(token)
if !checkTokenValid(actualToken) {
sendRequest(w, "Access Denied; Please check the access token",
http.StatusUnauthorized)
} else {
bytes, _ := json.Marshal(TimeResponse{
Time: time.Now().UTC().String(),
User: extractUserNameFromToken(actualToken),
})
w.Write(bytes)
}
}
func main() {
router := mux.NewRouter()
router.HandleFunc("/login", handleLogin).Methods(http.MethodPost)
router.HandleFunc("/healthCheck", healthCheck).Methods(http.MethodGet)
http.ListenAndServe(":8000", router)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment