jwtmidware

package module
v0.0.0-...-2f2d2fc Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 3, 2017 License: BSD-3-Clause Imports: 3 Imported by: 0

README

JSON WEB TOKEN Middleware

Build Status GoDoc Coverage Status

JSON WEB TOKEN authentication middleware for Gem Web framework.

Getting Started

Install

$ go get -u github.com/go-gem/middleware-jwt

Example

This package requires jwt package: https://github.com/dgrijalva/jwt-go.

package main

import (
	"html/template"
	"net/http"
	"sync"

	"github.com/dgrijalva/jwt-go"
	"github.com/go-gem/gem"
	"github.com/go-gem/middleware-jwt"
)

var form = `
    <html>
    <head>
    <title>JSON WEB TOKEN</title>
    </head>
    <body>
    <p><a href="/posts" target="_blank">POSTS LIST</a></p>

    <form id="signinForm" onsubmit="return false;" method="POST" action="/signin" accept-charset="UTF-8">
    <input type="text" name="username" id="username">
    <input type="button" value="Sign in!" onclick="signin(this);">
    </form>

    <form id="postForm" onsubmit="return false;" method="POST" action="/posts" accept-charset="UTF-8" style="display:none;">
    <input type="hidden" value="" id="{{.jwtFormKey}}" name="{{.jwtFormKey}}">
    <input type="text" name="title" id="title" name="title">
    <input type="button" value="Create Post!" onclick="createPost(this)">
    </form>
    <script type="text/javascript">
    	var signinForm = document.getElementById("signinForm");
    	var postForm = document.getElementById("postForm");
    	var username = document.getElementById("username");
    	var jwt = document.getElementById("{{.jwtFormKey}}");
    	var title = document.getElementById("title");

    	function signin(obj) {
		var xhr = new XMLHttpRequest();
       		xhr.open("POST", "/signin", true);
       		xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        	xhr.onreadystatechange = function () {
			if (xhr.readyState == 4 && xhr.status == 200) {
                    		var res = xhr.responseText;
                    		try{
                    			var json = eval('(' + res + ')');
                    			jwt.value = json.data.token;
                    			signinForm.style.display = 'none';
                    			postForm.style.display = 'block';
                    		} catch(err) {
                    			alert(err);
                    		} finally {

                    		}
                    		return;
                    	}
        	};

       		xhr.send("name=" + username.value);
    	}

    	function createPost(obj) {
		var xhr = new XMLHttpRequest();
       		xhr.open("POST", "/posts", true);
       		xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        	xhr.onreadystatechange = function () {
			if (xhr.readyState == 4 && xhr.status == 200) {
                    		var res = xhr.responseText;
                    		try{
                    			var json = eval('(' + res + ')');
                    			title.value = "";
                    			alert(json.msg);
                    		} catch(err) {
                    			alert(err);
                    		} finally {

                    		}
                    		return;
                    	}
        	};

       		xhr.send("title=" + title.value + '&_jwt=' + jwt.value);
    	}

	console.log("signinForm");
    </script>
    </body>
    </html>
    `

var (
	t = template.Must(template.New("index.tmpl").Parse(form))

	signMethod = jwt.SigningMethodHS256
	signKey    = []byte("secret-key")
	keyFunc    = func(token *jwt.Token) (interface{}, error) {
		return signKey, nil
	}

	// initial jwt middleware
	jwtMidware = jwtmidware.New(signMethod, keyFunc)
)

func main() {
	jwtMidware.NewClaims = func() jwt.Claims {
		return &userClaims{}
	}

	router := gem.NewRouter()
	router.GET("/", index)
	router.POST("/signin", signin)

	// posts handlers.
	router.GET("/posts", postsList)
	router.POST("/posts", postsAdd, &gem.HandlerOption{
		Middlewares: []gem.Middleware{jwtMidware},
	})

	gem.ListenAndServe(":8080", router.Handler())
}

func index(ctx *gem.Context) {
	t.ExecuteTemplate(ctx, "index.tmpl", map[string]interface{}{
		"jwtFormKey": jwtMidware.FormKey,
	})
}

var tokens []string

type userClaims struct {
	jwt.StandardClaims
	Name string `json:"name"`
}

// signin handler for distributing jwt token.
func signin(ctx *gem.Context) {
	name := ctx.Request.PostFormValue("name")
	claims := &userClaims{Name: name}

	token := jwt.NewWithClaims(signMethod, claims)
	encodedToken, err := token.SignedString(signKey)

	if err != nil {
		ctx.JSON(http.StatusInternalServerError, newResponse(-1, http.StatusText(http.StatusInternalServerError), nil))
		return
	}

	ctx.JSON(http.StatusOK, newResponse(0, "success", map[string]interface{}{
		"token": encodedToken,
	}))
}

type post struct {
	Title  string `json:"title"`
	Author string `json:"author"`
}

var (
	mutex = sync.Mutex{}
	posts = []post{
		post{Title: "first post", Author: "anonymity"},
	}
)

func postsAdd(ctx *gem.Context) {
	claims, ok := ctx.UserValue(jwtMidware.ClaimsKey).(*userClaims)
	if !ok || claims.Name == "" {
		ctx.JSON(http.StatusUnauthorized, newResponse(-1, http.StatusText(http.StatusUnauthorized), nil))
		return
	}

	mutex.Lock()
	defer mutex.Unlock()
	posts = append(posts, post{
		Title:  ctx.Request.PostFormValue("title"),
		Author: claims.Name,
	})

	ctx.JSON(200, newResponse(0, "success", nil))
}

func postsList(ctx *gem.Context) {
	ctx.JSON(200, newResponse(0, "success", map[string]interface{}{"posts": posts}))
}

type jsonResponse struct {
	Code int                    `json:"code"`
	Msg  string                 `json:"msg"`
	Data map[string]interface{} `json:"data"`
}

func newResponse(code int, msg string, data map[string]interface{}) jsonResponse {
	return jsonResponse{
		Code: code,
		Msg:  msg,
		Data: data,
	}
}

Documentation

Overview

Package jwtmidware JSON WEB TOKEN authentication for Gem Web framework.

This package requires jwt package: https://github.com/dgrijalva/jwt-go.

Example

package main

import (
	"html/template"
	"net/http"
	"sync"

	"github.com/dgrijalva/jwt-go"
	"github.com/go-gem/gem"
	"github.com/go-gem/middleware-jwt"
)

var form = `
    <html>
    <head>
    <title>JSON WEB TOKEN</title>
    </head>
    <body>
    <p><a href="/posts" target="_blank">POSTS LIST</a></p>

    <form id="signinForm" onsubmit="return false;" method="POST" action="/signin" accept-charset="UTF-8">
    <input type="text" name="username" id="username">
    <input type="button" value="Sign in!" onclick="signin(this);">
    </form>

    <form id="postForm" onsubmit="return false;" method="POST" action="/posts" accept-charset="UTF-8" style="display:none;">
    <input type="hidden" value="" id="{{.jwtFormKey}}" name="{{.jwtFormKey}}">
    <input type="text" name="title" id="title" name="title">
    <input type="button" value="Create Post!" onclick="createPost(this)">
    </form>
    <script type="text/javascript">
	var signinForm = document.getElementById("signinForm");
	var postForm = document.getElementById("postForm");
	var username = document.getElementById("username");
	var jwt = document.getElementById("{{.jwtFormKey}}");
	var title = document.getElementById("title");

	function signin(obj) {
		var xhr = new XMLHttpRequest();
		xhr.open("POST", "/signin", true);
		xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		xhr.onreadystatechange = function () {
			if (xhr.readyState == 4 && xhr.status == 200) {
				var res = xhr.responseText;
				try{
					var json = eval('(' + res + ')');
					jwt.value = json.data.token;
					signinForm.style.display = 'none';
					postForm.style.display = 'block';
				} catch(err) {
					alert(err);
				} finally {

				}
				return;
			}
		};

		xhr.send("name=" + username.value);
	}

	function createPost(obj) {
		var xhr = new XMLHttpRequest();
		xhr.open("POST", "/posts", true);
		xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		xhr.onreadystatechange = function () {
			if (xhr.readyState == 4 && xhr.status == 200) {
				var res = xhr.responseText;
				try{
					var json = eval('(' + res + ')');
					title.value = "";
					alert(json.msg);
				} catch(err) {
					alert(err);
				} finally {

				}
				return;
			}
		};

		xhr.send("title=" + title.value + '&_jwt=' + jwt.value);
	}

	console.log("signinForm");
    </script>
    </body>
    </html>
    `

var (
	t = template.Must(template.New("index.tmpl").Parse(form))

	signMethod = jwt.SigningMethodHS256
	signKey    = []byte("secret-key")
	keyFunc    = func(token *jwt.Token) (interface{}, error) {
		return signKey, nil
	}

	// initial jwt middleware
	jwtMidware = jwtmidware.New(signMethod, keyFunc)
)

func main() {
	jwtMidware.NewClaims = func() jwt.Claims {
		return &userClaims{}
	}

	router := gem.NewRouter()
	router.GET("/", index)
	router.POST("/signin", signin)

	// posts handlers.
	router.GET("/posts", postsList)
	router.POST("/posts", postsAdd, &gem.HandlerOption{
		Middlewares: []gem.Middleware{jwtMidware},
	})

	gem.ListenAndServe(":8080", router.Handler())
}

func index(ctx *gem.Context) {
	t.ExecuteTemplate(ctx, "index.tmpl", map[string]interface{}{
		"jwtFormKey": jwtMidware.FormKey,
	})
}

var tokens []string

type userClaims struct {
	jwt.StandardClaims
	Name string `json:"name"`
}

// signin handler for distributing jwt token.
func signin(ctx *gem.Context) {
	name := ctx.Request.PostFormValue("name")
	claims := &userClaims{Name: name}

	token := jwt.NewWithClaims(signMethod, claims)
	encodedToken, err := token.SignedString(signKey)

	if err != nil {
		ctx.JSON(http.StatusInternalServerError, newResponse(-1, http.StatusText(http.StatusInternalServerError), nil))
		return
	}

	ctx.JSON(http.StatusOK, newResponse(0, "success", map[string]interface{}{
		"token": encodedToken,
	}))
}

type post struct {
	Title  string `json:"title"`
	Author string `json:"author"`
}

var (
	mutex = sync.Mutex{}
	posts = []post{
		post{Title: "first post", Author: "anonymity"},
	}
)

func postsAdd(ctx *gem.Context) {
	claims, ok := ctx.UserValue(jwtMidware.ClaimsKey).(*userClaims)
	if !ok || claims.Name == "" {
		ctx.JSON(http.StatusUnauthorized, newResponse(-1, http.StatusText(http.StatusUnauthorized), nil))
		return
	}

	mutex.Lock()
	defer mutex.Unlock()
	posts = append(posts, post{
		Title:  ctx.Request.PostFormValue("title"),
		Author: claims.Name,
	})

	ctx.JSON(200, newResponse(0, "success", nil))
}

func postsList(ctx *gem.Context) {
	ctx.JSON(200, newResponse(0, "success", map[string]interface{}{"posts": posts}))
}

type jsonResponse struct {
	Code int                    `json:"code"`
	Msg  string                 `json:"msg"`
	Data map[string]interface{} `json:"data"`
}

func newResponse(code int, msg string, data map[string]interface{}) jsonResponse {
	return jsonResponse{
		Code: code,
		Msg:  msg,
		Data: data,
	}
}

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type JWT

type JWT struct {
	// See jwt.SigningMethod
	SigningMethod jwt.SigningMethod

	// See jwt.Keyfunc
	KeyFunc jwt.Keyfunc

	// FormKey be used to acquire token from query string
	// or post form.
	FormKey string

	// ContextKey be used to ctx.SetUserValue(ContextKey,jwt.Token)
	ContextKey string

	// NewClaims returns a jwt.Claims instance,
	// And then use jwt.ParseWithClaims to parse token and claims.
	// If it is not set, use jwt.Parse instead.
	NewClaims func() jwt.Claims

	// ClaimsKey be used to ctx.SetUserValue(ClaimsKey, jwt.Claims)
	ClaimsKey string
}

JWT is a HTTP middleware that provides JSON WEB Token authentication for Gem web framework.

func New

func New(signingMethod jwt.SigningMethod, keyFunc jwt.Keyfunc) *JWT

New returns a JWT instance via the given params and default configuration.

func (*JWT) Wrap

func (m *JWT) Wrap(next gem.Handler) gem.Handler

Wrap implements Middleware's interface.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL