Using Refresh Token in Asp.Net Core Web API Project

A refresh token is a special token that lets the user to refresh the access token without asking the user to login again. A refresh token will be generated with expiry time until that the user can make request for getting a new access token with the refresh token

Why Refresh token?

Uninterrupted User Experience:

            Usage of refresh token extends the session duration of user and prevents unnecessary reauthentication. For example, if an access token is only valid for 10 minutes, but the user is on the application for 15 minutes, the session may abruptly terminate. This is not ideal and leads to poor user experience. Usage of refresh token is a better approach, which enables new access tokens to be issued without a delay or additional effort

Improved Security:

            The use of refresh token makes it feasible to short the lifespan of access tokens. Since the access tokens are used for accessing APIs, any legitimate user that possesses it is considered authenticated without any additional identification. The longer the access token remains valid, the higher the risk of it becoming stolen. Pairing long duration of refresh tokens and short duration of access tokens enhances security.

What is Token Based Authentication?

            Before getting into example lets see what is token and token-based authentication is.

Tokens:

          Tokens are piece of data that carry which is been used to facilitate the process of identifying user’s identity and to authorize the user while accessing a protected resource in server.

            In token-based authentication, client will pass their credentials to the user at the time of login. The server verifies the credentials and if it is a valid user, then it will return a signed token to the client with an expiration time. The client can store the token in the client side and if the client makes any call to the server for data, then it does not need to send the credentials again and again instead pass the token to the server. The server validates the token and if it is a valid one, the server provides access to the data.

Access Tokens:

          Access tokens are short lived tokens used in token-based authentication to allow an application to access the APIs in the server. Access tokens are issued to after the user is successfully authenticated with valid credentials. While user makes request to the server, the access token will be passed as Bearer token in the request header. With this token the server understand that the bearer of the token is authorized to access the resource until the token gets expired  

Implementing Refresh token in web API Project

            Now we create a new web API project though .net CLI. Type the following command to create a new web API project.

dotnet new webapi -o newRefreshTokenProject

cd newRefreshTokenProject

 

Remove WeatherForecast.cs and WeatherForecastController.cs from the project folder

Install the following NuGet packages in your project

  • EntityFrameworkCore.SqlServer
  • AspNetCore. Authentication.JwtBearer
  • EntityFrameworkCore.Design
  • IdentityModel.Tokens
  • IdentityModel.Tokens.Jwt

Creating Models and Controllers

  • Create a new folder Models which contains entity classes of our application.
  • Create new .cs file UserModel.cs inside Models folder
  • Create new class User with the properties as shown below

User Model

UserModel.cs

Above you can see properties refresh token, dateCreated and tokenExpires. In our project we will generate a new refresh token at the time of user login and store it in our database along with the dateCreated property and tokenExpires which contains the validity and created date of refresh token

  • Create a new Sql database in SQL server
  • Add the connection string of newly created database in appsettings.json file as below

Appsettings.json

appsettings.json

  • Create a new context class by inheriting DbContext class
  • Add User class as Dbset property in the context class

UserContext.cs

  • Register your DbContext class in Program.cs file as a service with Dependency Injection. Pass your connection string from appsettings.json like below. These options will be passed to the base DbContext class

Program.cs

Program.cs

  • Create Migration to track all the changes that you made in the entity and context class by using the following command

dotnet ef migrations add <migration_name>

  • You will find a new folder name Migrations in your project folder.This migrations contains all the changes you made in the entity classes
  • To update these changes in your database use the following command.The following command updates all your changes in the database

dotnet ef database update

Create API for User Registration

  • Create a new controller UserController.cs under Controller folder
  • Specify the controller with [ApiController] attribute. This attribute indicates that the controller responds to web API requests.Controllers are just class which inherits the ControllerBase base class
  • Create an instance _context of UserContext class.
  • Inject the Dbcontext service in the UserController class and assign the value of instance to the local instance of UserContext class
  • Create an action method Register along with the attribute [HttpPost(“register”)].This attribute means that this action method can invoked when a POST request hits the endpoint “/api/user/register”

UserController

UserController.cs

It is good practice to use DTO classes for receiving inputs from the client. So, create DTO class named UserRequest.cs. Create property that you desire to get from the client

UserRequestDto

UserRequest.cs

Add the following code in your action method “Register”. The action method checks whether the username is already exists in the database or not.If yes it will send a response “Username already exists ”.If not it will hash the password received from the client and save the record in the database

UserRegister

UserController.cs with Action method for User Registration

Creating API for User Login

Create an action method named “Login” along with the [HttpPost (“login”)] attribute.

For this method create a DTO class named UserLoginRequest.cs with the properties username and password. I created separate services for generating tokens and hashing passwords and injected those services in the constructor via Dependency injection.

UserLogin

UserController.cs with Action method for User Login

In the above code you can find service GenerateAccessToken () and GenerateRefreshToken (). These services are used to generate access token and refresh token for the user. SetRefreshToken () service used to set the refresh token in response headers. Whenever the user sends request to the server you can find refresh token is been send to the server

Token Repository 1

Token Repository 2

TokenRepository.cs

In the above GenerateRefreshToken() service ,I created  an instance for RefreshToken class with the values for its properties. A random base64 string would be generated and assigned to the Token property. Current Date would be taken as value for Created property  and 7days from the created date would be taken as a value for the Expires property

SetRefreshToken() service set our refresh token in the cookies as HttpOnly cookie along with an expiry date.Then our refresh token will be appended with the response headers

Creating API for accessing Authorized Resources

Create an Action method called ProtectedAPI() which just returns a string “Protected Resource. You are authorized to access this resource”.Add [Authorize(Roles=”admin”)] attribute to make this action method can be accessed only by the users with role as admin.

ProtectedAPI

UserController.cs with API for Authorized User

 

Add Authentication service in the Program.cs with JwtBearerDefaults as default authentication scheme and Token Validation parameters and AddSecurityRequiremen() , AddSecurityDefinition() in AddSwaggerGen() service to enable authorization in swagger UI

 

Program.cs with Basic Authentication scheme and Security scheme for swagger

Now you can access the the protected API with the your access token.Now I Login with admin user I already created.

 

User Login with Swagger

Testing User Login with Swagger

Copy the access token and add it in the headers by clicking the Authorize option as bearer token

Setting Authorization Header in swagger with Bearer Token

Now call the protected API.Now you will see the response message

Accessing Protected resource

If you try to access the API without access token you will see an 401 Unauthorized Error response

Accessing Without Bearer Token

Check the network tab by using Ctrl+Shift+I shortcut key.Now you can see that our refresh token is been appended with the response headers and request headers.

Creating API for generating new Access token with Refresh Token

Now create an action method called Refreshtoken() with [HttpPost] attribute.

This action method extracts the refresh token from the Request header and check with the database whether any records match with this refresh token. If record not found it will send bad request as response. If not, it will check the expiry time of the refresh token. If the refresh token is valid one then this action method will send new access token as response to the user.

Conclusion:

            Implementing refresh token in your web API project helps you to add additional security to your resources by shortening the life time of access tokens. It is the responsibility of client side application to call API with refresh token while access token validity ends to generate new one

            I hope this blog provided an insight into refresh tokens and how you may utilize these in your applications. Find the source code in the GitHub link .

GitHub Link:  https://github.com/Pownraj-2818/Refresh_token_WebAPI.git

            Git is a free and open-source distributed version control system that can handle everything from tiny to extremely large projects quickly and efficiently. It was developed in 2005 by Linus Torvalds, creator of Linux Operating System.

To know more view: https://www.techmeet360.com/blog/global-information-tracker-git-workflow-and-terminologies/

 

 

 

 

 

 

 

Get notified about any future events

Interested in learning more about TechMeet360 or knowing about any future events? Sign up below to get notified.

Back to Top