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