Categorygithub.com/BeanCodeDe/authi
module
1.2.0
Repository: https://github.com/beancodede/authi.git
Documentation: pkg.go.dev

# README

Authi

A lightweight authentication service written in go

Build License made-with-Go GitHub go.mod Go version of a Go module

About

Authi is a lightweight authentication service written in go. It covers the basic use cases of creating and deleting users as well as refresh tokens and update passwords.


Getting started

For a fast setup you can use the following guide:

Create a folder structure that looks like this:

.
├── docker-compose.yml
└── myTokenFolder

Paste into the docker-compose.yml the following content

version: '3.7'
services:
  postgres:
    image: postgres:latest
    container_name: postgres
    restart: always
    environment: 
      - POSTGRES_PASSWORD=myDatabasePassword
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5 
  authi:
    image: "beancodede/authi:latest"
    container_name: authi
    restart: always
    environment: 
      - POSTGRES_PASSWORD=myDatabasePassword
    ports:
      - 1203:1203
    volumes: 
      - ./myTokenFolder:/token
    depends_on:
      postgres:
        condition: service_healthy
    links:
      - postgres:postgres

Execute the following two commands to generate key's

ssh-keygen -t rsa -b 4096 -m PEM -f ./myTokenFolder/jwtRS256.key
openssl rsa -in ./myTokenFolder/jwtRS256.key -pubout -outform PEM -out ./myTokenFolder/jwtRS256.key.pub

Note You need the cli programmes ssh-keygen and openssl in order to execute these commands

Start docker compose file

docker compose up

Note You need docker installed in order to execute this command


Configuration

The application can be started with different environment variables to configure specific behavior.

Name of environment variableDescriptionMandatoryDefault
LOG_LEVELLog level of console output. You can choose between debug, info, warn:x:info
ADDRESSServer address on that Authi runs:x:0.0.0.0
PORTServer port on that Authi runs:x:1203
PRIVATE_KEY_PATHPath to the RSA private key file for signing jwt tokens:x:/token/jwtRS256.key
PUBLIC_KEY_PATHPath to the RSA public key to validate jwt tokens:x:/token/jwtRS256.key.pub
DATABASEUsed database to store user data:x:postgresql
POSTGRES_USERUser of postgres database:x:postgres
POSTGRES_PASSWORDPassword of postgres database:heavy_check_mark:-
POSTGRES_DBDatabase name that should be used in postgres:x:postgres
POSTGRES_HOSTServer address of Postgres database:x:postgres
POSTGRES_PORTServer port oft Postgres database:x:5432
POSTGRES_OPTIONSConnection options of Postgres database:x:sslmode=disable
ACCESS_TOKEN_EXPIRE_TIMETime in minutes till an access token is no longer valid:x:5
REFRESH_TOKEN_EXPIRE_TIMETime in minutes till an refresh token is no longer valid:x:10
INIT_USER_FILEPath to the file with initial user:x:authi.conf

API Interface

The offered api interfaces can be find in this Swagger UI or in the folder /docs.

Adapter

To access the authi service from other go echo application, you can use the methods within the adapter package. Therefore two methods are provided:

GetToken(userId string, password string) (*TokenResponseDTO, error)

to get an access and refresh token with your userId and password.

RefreshToken(userId string, token string, refreshToken string) (*TokenResponseDTO, error)

to refresh your token for a logged in user without passing the password again.

Note You can only refresh tokens as long as your token and refresh token are valid.

To initial an authi adapter you have to use the method NewAuthiAdapter() within the adapter package.

The whole code could look like this:

func AdapterExample() {

	//User id that were previously created over REST
	userId := "693227c8-4178-4e72-b3b7-a8b8bae36f1b"

	//Generate UUID to trace your calls in the logs
	correlationId := uuid.NewString()

	//Initialize authi adapter
	authiAdapter := adapter.NewAuthiAdapter(correlationId)

	//Logging in previously created user with password `mySecretUserPassword`
	token, err := authiAdapter.GetToken(userId, "mySecretUserPassword")

	//Checking if an error occurred while loading user token
	if err != nil {
		panic(err)
	}

	//Printing access token for example
	fmt.Println(token.AccessToken)

	//Printing refresh token for example
	fmt.Println(token.RefreshToken)

	//Refreshing tokens to avoid outdated tokens
	refreshedToken, err := authiAdapter.RefreshToken(userId, token.AccessToken, token.RefreshToken)

	//Checking if an error occurred while loading refreshed token
	if err != nil {
		panic(err)
	}

	//Printing refreshed access token for example
	fmt.Println(refreshedToken.AccessToken)

	//Printing refreshed refresh token for example
	fmt.Println(refreshedToken.RefreshToken)
}

Middleware

If you write an echo go application, you also have the possibility to use the already attached middleware. Therefore you can orientate on the following example code:

func MiddlewareExample() {
	//Initialize parser to validate Tokens
	tokenParser, err := parser.NewJWTParser()

	//Checking if an error occurred while loading jwt parser
	if err != nil {
		panic(err)
	}

	//Initialize middleware
	echoMiddleware := middleware.NewEchoMiddleware(tokenParser)

	//Initialize echo
	e := echo.New()

	//Secure endpoint with method `echoMiddleware.CheckToken`
	e.GET(
		"/someEndpoint",
		func(c echo.Context) error { return c.NoContent(201) },
		echoMiddleware.CheckToken,
	)
}

Note In order for the code to work properly, the environment variable PUBLIC_KEY_PATH must point to the appropriate public key of the Authi server

While using the middleware the following errors could occur:

ErrorDescriptionInstruction
ErrTokenNotFoundToken was not found in requestDoes the passed token starts with "Bearer "; Is the token set in header Authorization inside the request
ErrClaimCouldNotBeParsedToken is valid but Claim format is unexpectedAre you using compatible version? Otherwise please create an issue
ErrTokenNotValidToken is not validA different key file may be used here for checking than is used in the Authi service. Otherwise, the token may have expired.
ErrWhileReadingKeyKey file couldn't be readMaybe the file is not on the correct position. Check your environment variable PUBLIC_KEY_PATH
ErrWhileParsingKeyKey file couldn't be parsedMaybe the file has not the correct format. Use the commands from Execute the following two commands to generate key's to generate key files

Init user configuration

To create users that are available immediately after starting the application, an init user config can be created. The default name of the file is authi.conf and must be right next to the application. If a different file path is desired, this can be adjusted via the environment variable INIT_USER_FILE. The startup process deletes all initial users and then creates the users from the file. Thus only the users with the most recent data from the file should remain as initial users.

The configuration file can be written in JSON or YAML. Mandatory fields are the ID of the user, which must be in uuid V4 format, and the user's password. Below are two example configurations in YAML and JSON:

{
    "users":[
        {
            "id": "c5ffc340-507e-4c66-a6ce-a7d98842f9ba",
            "password":"someSecretPassword"
        },
        {
            "id":"5cc3621d-e5ac-4d81-93df-462b27e0cc2b",
            "password":"someOtherPassword"
        }
    ]
}
users:
    -   
        id: c5ffc340-507e-4c66-a6ce-a7d98842f9ba
        password: someSecretPassword
    - 
        id: 5cc3621d-e5ac-4d81-93df-462b27e0cc2b
        password: someOtherPassword

# Packages

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author