Skip to content

Instantly share code, notes, and snippets.

@mhewedy
Created August 10, 2019 20:50
Show Gist options
  • Save mhewedy/4e45e04186ed9d4e3c8c86e6acff0b17 to your computer and use it in GitHub Desktop.
Save mhewedy/4e45e04186ed9d4e3c8c86e6acff0b17 to your computer and use it in GitHub Desktop.
Example with custom authentication and authorization with echo go web framework
package main
import (
"fmt"
"github.com/dgrijalva/jwt-go"
"github.com/labstack/echo"
"github.com/labstack/echo/middleware"
"net/http"
"time"
)
type User struct {
Username string `json:"username"`
Password string `json:"password"`
}
func login(c echo.Context) error {
user := User{}
if err := c.Bind(&user); err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
}
if user.Username != "jon" || user.Password != "shhh!" {
return echo.ErrUnauthorized
}
token, err := createToken("John snow", []string{"admin"})
if err != nil {
return err
}
return c.JSON(http.StatusOK, map[string]string{
"token": token,
})
}
func createToken(name string, roles []string) (string, error) {
token := jwt.New(jwt.SigningMethodHS256)
claims := token.Claims.(jwt.MapClaims)
claims["name"] = name
claims["roles"] = roles
claims["exp"] = time.Now().Add(time.Hour * 24 * 10).Unix()
t, err := token.SignedString([]byte("secret"))
return t, err
}
func accessible(c echo.Context) error {
return c.String(http.StatusOK, "Accessible")
}
func restricted(c echo.Context) error {
user := c.Get("user").(*jwt.Token)
claims := user.Claims.(jwt.MapClaims)
name := claims["name"].(string)
roles := claims["roles"].([]interface{})
return c.String(http.StatusOK,
fmt.Sprintf("Welcome %s, you have roles: %v\n", name, roles))
}
func SkipperFn(skipURLs []string) func(echo.Context) bool {
return func(context echo.Context) bool {
for _, url := range skipURLs {
if url == context.Request().URL.String() {
return true
}
}
return false
}
}
func main() {
e := echo.New()
// Middleware
e.Use(middleware.Recover())
e.Use(middleware.Logger())
e.Use(middleware.JWTWithConfig(middleware.JWTConfig{
SigningKey: []byte("secret"),
Skipper: SkipperFn([]string{"/api/v1/login", "/"}),
}))
// Login route
e.POST("/api/v1/login", login)
e.GET("/", accessible)
e.GET("/api/v1/me", restricted)
e.Logger.Fatal(e.Start(":8000"))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment