Implementing JWT Authentication between ASP.NET Core and React

JSON Web Token (JWT) authentication is a widely used authentication method in web development. In this blog post, we will discuss how to implement JWT authentication between an ASP.NET Core backend and a React frontend.

Introduction

JSON Web Token (JWT) is an open standard for creating tokens that securely transmit information between parties. JWT authentication works by generating a token on the server and sending it to the client. The client then stores the token and sends it with subsequent requests to the server for authentication.

Step-by-Step Implementation

1. Setting up the ASP.NET Core Backend

First, we need to set up the ASP.NET Core backend to generate a JWT token. We will use the Microsoft.AspNetCore.Authentication.JwtBearer package to handle JWT authentication. Here is an example code snippet:

// ConfigureServices method in Startup.cs file
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = Configuration["Jwt:Issuer"],
            ValidAudience = Configuration["Jwt:Audience"],
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
        };
    });

In the above code, we are adding JWT authentication to the ASP.NET Core application. We are setting the token validation parameters, such as the issuer, audience, lifetime, and signing key. We are also specifying the JwtBearerDefaults.AuthenticationScheme as the default authentication scheme.

2. Generating a JWT Token on Login

When a user logs in, the server generates a JWT token and sends it back to the client. Here is an example code snippet:

[HttpPost("login")]
public async Task<IActionResult> Login([FromBody] LoginViewModel model)
{
    var user = await _userManager.FindByNameAsync(model.Username);

    if (user != null && await _userManager.CheckPasswordAsync(user, model.Password))
    {
        var tokenHandler = new JwtSecurityTokenHandler();
        var key = Encoding.ASCII.GetBytes(_configuration["Jwt:Key"]);
        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(new Claim[]
            {
                new Claim(ClaimTypes.Name, user.UserName),
                new Claim(ClaimTypes.Role, "Administrator")
            }),
            Expires = DateTime.UtcNow.AddDays(7),
            SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
        };

        var token = tokenHandler.CreateToken(tokenDescriptor);
        var tokenString = tokenHandler.WriteToken(token);

        return Ok(new { Token = tokenString });
    }

    return Unauthorized();
}

In the above code, we are generating a JWT token on successful login. We are using the JwtSecurityTokenHandler class to create a token and the SecurityTokenDescriptor class to specify the token’s claims and expiration time. We are also specifying the signing key and algorithm. Finally, we are returning the token string to the client.

3. Storing the JWT Token in Local Storage

The client needs to store the JWT token so that it can be sent with subsequent requests to the server for authentication. One way to store the JWT token is to use localStorage, which is a browser object that allows you to store data. Here is an example code snippet:

// Function to store JWT token on successful login
function setToken(token) {
  localStorage.setItem('token', token);
}

// Function to get JWT token
function getToken() {
  return localStorage.getItem('token');
}

In the above code, we are using the `localStorage.setItem()` method to store the JWT token in the browser’s local storage. We are using the key `’token’` to identify the token. We are also using the `localStorage.getItem()` method to retrieve the token.

4. Sending the JWT Token with Subsequent Requests

The client needs to send the JWT token with subsequent requests to the server for authentication. We can use the `Authorization` header to send the token. Here is an example code snippet:

// Function to send HTTP requests with JWT token
function fetchWithToken(url, options) {
  const token = getToken();

  if (token) {
    options = {
      ...options,
      headers: {
        'Authorization': `Bearer ${token}`
      }
    };
  }

  return fetch(url, options);
}

In the above code, we are creating a fetchWithToken() function that sends HTTP requests with the JWT token. We are retrieving the token from localStorage using the getToken() function. We are then adding the token to the Authorization header in the options object.

5. Handling Unauthorized Requests

If the JWT token is invalid or expired, the server will return a 401 Unauthorized response. In this case, the client needs to clear the JWT token from localStorage and redirect the user to the login page. Here is an example code snippet:

// Function to handle unauthorized requests
function handleUnauthorized() {
  localStorage.removeItem('token');
  window.location.href = '/login';
}

In the above code, we are creating a handleUnauthorized() function that removes the JWT token from localStorage and redirects the user to the login page.

Conclusion

In this blog post, we have discussed how to implement JWT authentication between an ASP.NET Core backend and a React frontend. We have covered generating a JWT token on login, storing the token in localStorage, sending the token with subsequent requests, and handling unauthorized requests. By implementing JWT authentication, you can ensure that only authenticated users can access your application’s resources.


날짜:

카테고리:

태그: