Build an Authentication Server

Postgres Setup

Create role & database

I am going to use PostgreSQL for this project, so let's create a database. The superuser on my computer is cfeng. If you don't have a role or wish to create a separate role for this project, then just do the following

$ psql postgres
postgres=# create role <name> superuser login;

Create a database named go_academy_userauth with owner pointing to whichever role you like. I am using cfeng on my computer.

$ psql postgres
postgres=# create database go_academy_userauth with owner=cfeng;

Actually just in case you don't remember the password to your ROLE, do the following

postgres=# alter user <your_username> with password <whatever you like>

Example

Create cfeng

postgres=# create role cfeng superuser login;

Create database

postgres=# create database go_academy_userauth with owner=cfeng;

Update password

Project Dependencies

I am going to introduce couple new open source libraries for this project:

  • spf13/cobra

  • sirupsen/logrus

  • labstack/echo

  • jinzhu/gorm

Project User Authentication

This project is going to use JWT based authentication instead of the traditional session based authentication. For the detailed comparison of the two, take a look at this article.

This project is not going to use real JWT for simplicity sake, instead it uses a mock token. A real token can be generated using verified open source libraries, for more information go to JWT.io.

Nevertheless, it is important to show how JWT authentication works.

Authentication Endpoints

We expose endpoints on the server for users to sign in (authenticate) or register an account. The server is responsible for returning a token to the client side. Once user receives the token, he/she will embed this token into his/her request headers when he/she needs to access resources from the user. In practice, we would have two different services to complete the whole authentication cycle but we will combine the two services into one for this project.

Authenticate

POST http://localhost:8000/api/authenticate/

Authenticate a user

Request Body

Name
Type
Description

email

string

email of the account

password

string

password of the account

Register

GET http://localhost:8000/api/register/

Register a new user

Request Body

Name
Type
Description

name

string

name of the new user

email

string

email of the new user

password

string

password of the new user

Once front end receives the token, it should put it into local storage. Next time when user opens his/her browser, the client application should use the same token to verify that user is indeed signed in.

User Resource Endpoints

Since we are not using real JWT token, front end needs to make requests to server to ask for user information. We need to expose some user endpoints for that.

Users

GET http://localhost:8000/api/users/

Fetch the list of all users

Headers

Name
Type
Description

Token

string

token to authenticate with server

Current User

GET http://localhost:8000/api/users/current/

Fetch current user

Headers

Name
Type
Description

Token

string

token to authenticate with server

Message Resource Endpoints

Users can send messages to each other. When a user signs in to the system, he/she should be able to view all the sent and received messages.

Send Message

POST http://localhost:8000/api/messages/

Send a message to another user

Headers

Name
Type
Description

Token

string

token to authenticate with server

Request Body

Name
Type
Description

receiver_id

integer

integer ID of the message receiver

body

string

message body

Users can see their own list of received and sent messages.

Sent Messages

GET http:localhost:8000/api/messages/sent/

Fetch the list of current user's sent messages

Headers

Name
Type
Description

Token

string

token to authenticate with server

Received Messages

GET http://localhost:8000/api/messages/received/

Fetch the list of current user's received messages

Headers

Name
Type
Description

Token

string

token to authenticate with server

Models

There are two primary resources on our server, i.e. users and messages.

Migrations

Instead of using auto migration feature of GORM, I prefer to write our own SQL because it gives us greater flexibility and better organization.

Put everything together

Let's start off with creating a skeleton for the project. Details will be discussed in the video section. Create a project file structure as follows.

Inside the main.go, set up logging and cobra commands.

Create two commands inside cmd package, one for migration and one for running server.

Video

Now your project should be able to compile and you should be able to run migration on the database.

In the video, I will discuss how to write each endpoint.

Additional Resource

If you want to learn more about session storage, security, encryption, and many other topics relating to web applications, take a look at this GitBook.

Source

GitHub

Last updated