How To Secure Your Golang Application
Configure authentication and authorization without harming the principle of statelessness of REST

Imagine a customer wanting you to develop an online ticket API. They have some requirements:
- Three user types: admin, individual user, corporate user
- Admin has extra privileges beyond the user’s authorization scope, and Admin’s authorization scope includes other user types’ authorization scope.
We do not go into detailed logic of the project. We are just interested in how we can understand clients’ roles and their scope of authority depending on their roles.
User types would have their own business rules, restrictions, and authority.
To sum up, these are the general problems you need to take care of:
- Authentication: You need to verify the identity of each client who requests your API.
- Authorization: You need to identify the roles and match clients with these roles. For example, the admin and individual users have different permission types to perform certain actions or access a certain resource. Therefore, you need to determine each client’s user type when logging into your system. Hereby, you can define their scope of authority.
Let’s try to figure out how we configure authentication and authorization without harming the principle of statelessness of REST.
Authentication
First, the client must register online ticket system with some information about them:
Username
, Password
, UserType
(admin, corporate, or individual user), and Email
.

When the client registers, our system saves this information to the database after the above validations and sends a welcome e-mail to the client.
Second, the client must log in with their username and password (credentials). The story actually begins here.

We need to check the validity of both the username and password in the service layer:
First, we go to the database to check if this username exists in our client. If it exists, we check whether the password and hashed password are the same.
If username and password are not correct:

If the username and password are correct, this means the authentication step is successful, and the user can successfully log in to the system via generated JWT token.
Authorization
After this authentication step, we define JWT(JSON Web Token).
JWT is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. JWT can be verified and reliable because it is digitally signed.
Once the user is logged in, each subsequent request must include the JWT, allowing the user to access routes, services, and resources permitted with that token [1].
To provide statelessness, we use a token-based technique. Because it uses tokens in each request made from client to server, it doesn't store any information about the client. This would provide an advantage when one server is overloaded. The request can be directed to another server without any additional burden. In addition, we can easily scale our servers.
We combine token-based authentication with JWT to store data. We get these data via auth.Claims{}
and create JWT by using it and storing that JWT in cookies.
Now, our API should be a Private API. Users must register to our system to benefit from our API’s magical potential. 🪄
How do we prevent unregistered clients and unauthorized access from enjoying the features of our magic API?
When we think logically, there are some repetitive tasks:
- We need to check whether a token has come in each HTTP request for all defined endpoints except for register and log in.
- After authenticating the client’s credentials, if the client is an admin, she must have additional privileges while using our API, for example, creating a new trip, canceling a trip, etc.
Therefore, because of these repetitive tasks, we don't want to write this validation logic for all the necessary endpoints, so we used two middlewares for this purpose.

- Token middleware
Token middleware authenticates the client’s credentials in each request. Because this API is private, we use this middleware for all endpoints (except /register
and /login
as you can see in allowList
)
- Admin middleware
This middleware is used to define the admin’s additional privileges.
Admin can create and cancel trips and see sold ticket numbers and total revenue. These additional functionalities are not available for you, and you may even have no awareness of the existence of these endpoints if you are not an admin.
Conclusion
As mentioned, we did not go into detail whole project logic. In this article, we focused on authentication and authorization problems.
Authentication verifies the identity of a client before granting access to our system, while authorization grants or denies access to specific resources based on the user’s identity and permissions.
With token-based authentication, the client’s data are saved in cookies, and we use these data for authorization purposes. We use middleware for both authentication and authorization processes.
Thank you for reading :)