Skip to content

Jwt Token Auth in Golang

   

A Go module that exposes basic operations for user management in a REST context (signup, signin, refresh, logout) using JWT.

For more detailed information about the JSON Web Token (JWT) standard, you can look here

Some features in this implementation:

  • User signup, signin, refresh and logout supported
  • The JWT Token is passed in the requests’ header like: “Authorization: Bearer THE_TOKEN”
  • User management with persistence on disk (simple text file)
  • User log out feature using jwtToken white listing.
  • Hash the passwords stored locally
  • Support saving roles for the user

You can take a look at the code

Building and running

go build -o jwt-go-server
./jwt-go-server

Sign up a new user:

curl -X POST -i -H "Accept: application/json" -H "Content-Type: application/json" --data '{"username":"newuser","password":"newpass"}' http://localhost:8000/signup

Upon sign up the user is created and saved in the server users file (by default “usersDB” created in the same directory where the server is running).
The user is created with the default role “CLIENT”

Sign in with the new user:

curl -X POST -i -H "Accept: application/json" -H "Content-Type: application/json" --data '{"username":"newuser","password":"newpass"}' http://localhost:8000/signin

If the sign in is valid, in the response you get the JWT token valid for X time (configurable, default is 5 minutes) to be used in further requests with Authorization.

Example endpoint that enforces authentication

curl -X GET -i -H "Authorization: Bearer <your-jwt-token>" http://localhost:8000/welcome

In this example, we call a secured endpoint that checks the JWT token. If it’s valid, not expired and if any of the roles of the user is configured for this endpoint, you’ll get the response.

An example for this output:

curl -X GET -i -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Im5ld3VzZXIiLCJyb2xlcyI6WyJDTElFTlQiXSwiZXhwIjoxNjE0NDIwNDEwfQ.a8rGllUEjkPzM4vgnwD0PaIvRSmx5fZ8glGC-QzVBaY" http://localhost:8000/welcome
HTTP/1.1 200 OK

Welcome newuser!
 Your roles are: [CLIENT]

Refresh endpoint to get a new token

curl -X GET -i -H "Authorization: Bearer <your-jwt-token>" http://localhost:8000/refresh

A new JWT token will be issued only if the current token is within some X time (configurable, default is 30 seconds) before expiration time. Otherwise it returns the same token.

Logout

curl -X GET -i -H "Authorization: Bearer <your-jwt-token>" http://localhost:8000/logout

It takes the passed token out of the whitelist, it cannot be used again (so it works as a logout)

Main code that can be used as template

The following code snippet shows how to use the library.
Adding routes to the basic user management operations (SignUp, SignIn, Refress, LogOut).
Also, it shows how to wrap your custom endpoints (E.g: /welcome) so they are secured by JwtToken

package main

import (
	"fmt"
	"github.com/miguelabate/jwt-go-mabate/jwthandler"
	"github.com/miguelabate/jwt-go-mabate/users"
	"log"
	"net/http"
)

func main() {
	fmt.Println("Starting JWT Go server ...")
	// provided
	http.HandleFunc("/signin", jwthandler.SignIn)
	http.HandleFunc("/signup", jwthandler.SignUp)
	http.HandleFunc("/refresh", jwthandler.Refresh)
	http.HandleFunc("/logout", jwthandler.Logout)

	// custom
	http.HandleFunc("/welcome", jwthandler.WithJwtCheck(Welcome, []string{"CLIENT", "ADMIN"}, true))

	// can override some config values
	//users.PersistenceUsersFileLocation = "altUserDB"
	//jwthandler.JwtTokenLifeInMinutes = 10
	//jwthandler.JwtTokenRefreshPeriodInSeconds = 60

	users.LoadUsersFromDB()

	//// start the server on port 8000
	log.Fatal(http.ListenAndServe(":8000", nil))

}

func Welcome(w http.ResponseWriter, r *http.Request, jwtToken *jwthandler.MaJwt) {
	// username given in the token
	w.Write([]byte(fmt.Sprintf("Welcome %s!\n Your roles are: %s", jwtToken.Claims.Username, jwtToken.Claims.Roles)))
}

The code can be found in https://github.com/miguelabate/jwt-go-mabate

Related Posts

  1. Reddit Urls Scraper
  2. Protobuf communication between Js-client and Go-server