Skip to content

Auth middleware and wrapper in GO. Supports username/password, register, login, change password with role restriction

License

Notifications You must be signed in to change notification settings

hieunc229/eveauth

Repository files navigation

EveAuth

Auth middleware and request handler wrapper for GO. It uses boltDB to store user data

Included in this guide:

  1. Usage
  1. Changelog
  2. Feedback and Contribute
  3. Licenses

1. Getting started

Install

$ go get github.com/hieunc229/eveauth

Auth Handle Wrapper and Middleware

Use eveauth.AuthMiddleware or eveauth.AuthHandler to authorize users.

import (
    "github.com/hieunc229/eveauth"
)

// It can be used for any router with standard handler
// ie. func (http.ResponseWriter, r *http.Request)
router := mux.NewRouter()

// auth options
authOptions := eveauth.AuthHandlerOptions{
    // allow only member
    // other values can be eveauth.RoleAdmin, eveauth.RoleAnonymous
    Role: eveauth.RoleMember,

	// Set to true to forbid access from users with different RoleLevel.
	// Or set to false (or nil) to forbid only users with lower RoleLevel
    RoleExact: true
}

// Use as middleware
router.Use("/user_only", eveauth.AuthMiddleware(&authOptions))

// Or wrap around a handler
router.HandlerFunc("/user_only", eveauth.AuthHandler(yourHandler, &authOptions))

When there is an anonymous request to these paths, it return the following:

{
    "ok": false,
    "error": "invalid access"
}

Register handler

Use eveauth.RegisterHandler handler to handle create account. Registed users will have eveauth.RoleMember role

router.HandlerFunc("/auth/register", eveauth.RegisterHandler)

The body json data must be:

{
    "data": {
        "username": "xxxxxx",
        "password": "xxxxxx"
    }
}

Success return:

{
    "ok": true
}

Error return:

{
    "error": "error message",
    "ok": false
}

Login handler

Use eveauth.LoginHandler handler to handle login

router.HandlerFunc("/auth/login", eveauth.LoginHandler)

The body json data must be:

{
    "data": {
        "username": "xxxxxx",
        "password": "xxxxxx"
    }
}

Success return:

{
    "data": {
        "token": "jwt token str" // use as bearer token
    },
    "ok": true
}

Error return:

{
    "error": "error message",
    "ok": false
}

Change password handler

Use eveauth.ChangePasswordhandler to handle change password request. Note that the request must be authorized with Bearer token mention above. If you don't have a bearer token, login to get a bearer token first

router.HandlerFunc("/auth/change-password", eveauth.ChangePasswordhandler)

The body json payload must be:

{
    "data": {
        "password": "oldPassword",
        "new_password": "xxxxxxx",

        //// set to `true` to replace the current token with a new one
        "change_token": false, 

        // set to `true` to remove all existing tokens, then add a new one 
        // (i.e useful for logout all other devices feature)
        "clear_tokens": false, 
    }
}

Success response:

{
    "data" {
        // If `change_token` or `clear_tokens` is true, you will need to use this new token
        // Otherwise, this value will be an empty string ("")
        "new_token": "" 
    },
    "ok": true
}

Error response:

{
    "error": "error message",
    "ok": false
}

Here is a change password example using fetch in JavaScript

fetch("/user_only/items/goodItemId", {
    method: "POST",
    headers: {
        'Authorization': 'Bearer <token>'
        // 'Content-Type': 'application/json'
        // ...
    }
    body: JSON.stringify({
        data: {
            password: "xxxxx",
            new_password: "xxxxxxxx"
        }
    })
})

How to use JWT token

After send a login request and receive a sucess response, you'll be given a token. This token is meant to use as Bearer token.

Whenever you make a request and want it to be authorized, added Authorization: Bearer <token> to the request header

Here is an example with fetch in JavaScript

fetch("/user_only/items/goodItemId", {
    method: "POST",
    headers: {
        'Authorization': 'Bearer <token>'
        // 'Content-Type': 'application/json'
        // ...
    }
    // body: ...
})

How to verify a request contains a JWT token

Use eveauth.VerifyRequest(*http.Request, *eveauth.AuthHandlerOptions) (*JWTPayload, err) to verify your http request.

Verify a http.Request by (1) get bearer token, (2) verify if the token is a valid jwt token, (3) get userData then check if token is still active (4) then check if the user has the proper role if authOption != nil

Here is an example:

func yourHandler(w http.ResponseWriter, r *http.Request) {

    payload, err := eveauth.VerifyRequest(r, &eveauth.AuthHandlerOptions{})

    if err != nil {
        // bearer token is not valid or expired
        return;
    }

    // no err, looking good

    username = payload.Username
}

Setup enviroment variables

There are a few enviroment variables that you should update when using the product:

  • EVEAUTH_JWT_SECRET (default eveauth): a secret string to create jwt token
  • EVEAUTH_PATH (default auth): path to your auth database. You can use absolute or relative path. If you use relative path, the path root is where you run the command)

There are 2 ways to set these enviroment variables:

  1. Using flags in command (only used after you build the application (aka binary file)). For example:
$ ./coolapp -EVEAUTH_JWT_SECRET=randomstringnoonecanguess -EVEAUTH_PATH=/ect/safe-area/coolappAuth.db
  1. Use godotenv (or any dotenv alternative). First, install godotenv (go get https://github.com/joho/godotenv), then create a .env at your root directory with the following content:
# .env
EVEAUTH_JWT_SECRET=randomstringnoonecanguess
EVEAUTH_PATH=/ect/safe-area/coolappAuth.db
  1. Load the .env file. Read the manual from dotenv package you use. For example, for godotenv:
package main

import (
    ...
    "github.com/joho/godotenv"
)

func main() {

    // Load .env file
    err := godotenv.Load()
    if err != nil {
        log.Fatal("Error loading .env file")
    }

}

2. Changelog

  • 25 Jun 2021: added roles
  • 24 Jun 2021: initiate project

3. Feedback and Contribute

Always welcome. Please open a new thread

4. Licenses

  • eveauth MIT
  • BoltDB MIT

About

Auth middleware and wrapper in GO. Supports username/password, register, login, change password with role restriction

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages