Sitemap
wesionaryTEAM

Visionary Development Team. We ❤︎ Technology!

Authorization in Golang Projects using Casbin

JWT Authentication | GIN | GORM

5 min readJun 25, 2021

--

Press enter or click to view image in full size
Image

Hello Developers 👋👋. In this article, we will implement Casbin alongside JWT Authentication in Golang(GIN+GORM) Project.

Before going through this article, I highly suggest checking out another article written by me about the basics of casbin and its different model configurations.

Implementation

I will like to show the folder structure beforehand so that it is easy to follow. You can check my GitHub repository for full code if you get lost somewhere.

Folder Structure

Image
Folder Structure

RBAC MODEL (config/rbac_model.conf)

If you have no idea about models in casbin, do check this article. You will find a detailed explanation there. I will be using RBAC Model for this article.

GORM DATABASE

We will use GORM for accessing the database. The following code simply creates a new database connection and returns that connection which will be used in other parts of the code in the sections below.

ROUTE

This is the main section of the article which connects casbin, our custom middlewares and handler methods(which we will create in the following sections)

Let me explain the above codes briefly

  • [Line 3]: Here we set up the default Gin Router
  • [Line 6]: Here we set up the Gorm adapter for Casbin. With this adapter, Casbin can load policy from Gorm supported database or save policy to it. This will also create a table named casbin_rule
  • [Line 12]: Here we construct a casbin enforcer by providing our modal(RBAC constructed above) and gorm adapter(from Line 6) as an argument.
  • [Line 17 - 26]: Here we load the policy needed for our application to the database. This is a one-time operation. So it would be better to add policy with some command independent of the main program flow. But for simplicity, I have added policy ( enforcer.AddPolicy ) in the main program flow itself but only after ensuring if that policy is not already present ( enforcer.HasPolicy )in the database.
Image
The doctor can read/write reports but the patient can only read reports.
  • [Line 44–49]: Here we have protected individual routes with the casbin middleware(which we will construct later).

UTILS

I would like to show some utility functions beforehand which will be used in different sections of the code below. All of them are very straightforward.

MIDDLEWARE

JWT AUTHENTICATION

I will not go into details about authentication in this article. You can use any authentication modules like JWT, Firebase Authentication, AWS Cognito. I will be showing JWT codes here.

The above code is a middleware that is used for ensuring if the user has a valid token.

Get Dipesh KC’s stories in your inbox

Join Medium for free to get updates from this writer.

The only thing I want to highlight here is we are setting userID in the context [Line 22] which is retrieved from the token. This userID will be used for authorization later.

CASBIN MIDDLEWARE

The purpose of this middleware is to ensure if the user has the right permission or has the authority to perform a certain task.

Authorize method accepts 3 parameters namely obj, act, and enforcer. obj is the resource he is trying to access. act is the action he is trying to do on that resource. enforcer is casbin Enforcer which we initialized in the above route section.

  • [Line 5]: Here we are retrieving the sub which is userID from the context to know who is trying to perform a certain action on the resource
  • [Line 12]: Here we are loading all the policy available in the Database (which we added in the above route section)
  • [Line 19]: Here we are using casbin enforce method to find out if the user should be granted access or should be denied.

USER MODEL

This is the model we will use for the registration/login process [ in later sections ]. Here role is just for retrieving the user’s role from the frontend. It will not be stored in the database. Hence gorm:”-” is used

REGISTER

The purpose of this method is to register users.

  • [Line 4–8]: We are retrieving user information from the frontend
  • [Line 11–16]: We are adding retrieved user information to the database
  • [Line 17]: We are adding user role to the casbin_rule table using enforcer.AddGroupingPolicy method.

When we hit POST /register

Frontend Request

Press enter or click to view image in full size
Image
Frontend Request

User Table

John with id 8 is added to the users table.

Press enter or click to view image in full size
Image
users Table

Casbin Table

user_id of 8(John)(v0) with role doctor(v1) of type g(role/group) is added to the casbin_rule table.

Image
casbin_rule Table

LOGIN

The purpose of this method is to make users able to log in to our system.

The above code retrieves the login information[Line 2–5] and checks if that email is available on the database[Line 7–12] and also verify if the password is correct [Line 13–18].

MAIN PROGRAM

Running the Project

If a user with patient role tries to access PUT users/:user i.e tries to update the user, he will not be allowed to do so.

Image

CONCLUSION

If you get lost on any part you can check my Github project.

This is the end of our short journey of understanding casbin and implementing casbin on the golang projects. Hope this will help you with your project. Any kind of suggestions would be highly appreciable. Happy Coding ☺.

--

--

Responses (2)