返回

保护接口,使用 JWT - 提升博客项目的安全性

后端

引言

欢迎来到 StarBlog 系列的 2023 年第二篇更新!最近一段时间,我一直在忙于其他事情,导致更新频率有所下降。但我也知道,长时间不更新会让人感到不安,所以我决定还是继续更新,哪怕是慢慢地。

言归正传,在之前的文章中,我们已经讨论了博客的关键接口。现在,是时候考虑如何保护这些接口的安全了。毕竟,博客中可能包含一些敏感信息,比如用户的个人数据或文章内容。如果这些信息被泄露,可能会对用户或博客本身造成损害。

什么是 JWT?

JWT(JSON Web 令牌)是一种流行的用于安全传输信息的标准。它由三部分组成:头部、有效载荷和签名。头部包含有关 JWT 元数据的信息,例如使用的算法和令牌类型。有效载荷包含实际数据,例如用户 ID 或用户名。签名用于验证令牌的完整性和真实性。

JWT 的工作原理

JWT 通常由服务器生成并发送给客户端。客户端存储 JWT,并在需要访问受保护资源(例如 API 端点)时将其发送给服务器。服务器验证 JWT 的签名并提取有效载荷中的信息。如果 JWT 有效,则服务器将允许客户端访问受保护的资源。

在 StarBlog 中使用 JWT 保护接口

现在,我们了解了 JWT 的工作原理,就可以将其应用到 StarBlog 项目中了。首先,我们需要在项目中安装 JWT 库。我推荐使用 Microsoft.AspNetCore.Authentication.JwtBearer 包。

安装好 JWT 库后,就可以在 Startup.cs 文件中配置 JWT 中间件。在 ConfigureServices 方法中,添加以下代码:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your_secret_key")),
            AudienceValidator = ValidateAudience
        };
    });

在上面的代码中,我们配置了 JWT 中间件并设置了令牌验证参数。这些参数告诉 JWT 中间件如何验证收到的 JWT 令牌。

接下来,我们需要在控制器中使用 JWT 中间件。在需要保护的控制器中,添加 [Authorize] 特性。例如:

[Authorize]
public class PostsController : Controller
{
    // 控制器的方法
}

添加了 [Authorize] 特性后,只有拥有有效 JWT 令牌的客户端才能访问 PostsController 中的方法。

最后,我们需要生成 JWT 令牌。我推荐使用 Microsoft.IdentityModel.Tokens 库来生成 JWT 令牌。

在 StarBlog 项目中,我们可以创建一个 JWT 服务来生成 JWT 令牌。在 Services 文件夹中,创建一个 JWTService.cs 文件,并添加以下代码:

using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

public class JWTService
{
    private readonly string _secretKey;

    public JWTService(IConfiguration configuration)
    {
        _secretKey = configuration.GetValue<string>("Jwt:SecretKey");
    }

    public string GenerateToken(User user)
    {
        var tokenHandler = new JwtSecurityTokenHandler();
        var key = Encoding.UTF8.GetBytes(_secretKey);
        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(new Claim[]
            {
                new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
                new Claim(ClaimTypes.Name, user.Username)
            }),
            Expires = DateTime.UtcNow.AddMinutes(30),
            SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
        };
        var token = tokenHandler.CreateToken(tokenDescriptor);
        return tokenHandler.WriteToken(token);
    }
}

在上面的代码中,我们创建了一个 JWT 服务。这个服务可以生成 JWT 令牌。

现在,我们就可以在我们的控制器中使用 JWT 服务来生成 JWT 令牌了。例如,在 UserController 中,我们可以添加以下代码:

public class UserController : Controller
{
    private readonly JWTService _jwtService;

    public UserController(JWTService jwtService)
    {
        _jwtService = jwtService;
    }

    [HttpPost("login")]
    public IActionResult Login([FromBody] LoginModel model)
    {
        var user = _userService.GetUserByUsername(model.Username);
        if (user == null || user.Password != model.Password)
        {
            return Unauthorized();
        }

        var token = _jwtService.GenerateToken(user);
        return Ok(new { token });
    }
}

在上面的代码中,我们使用 JWT 服务生成了一个 JWT 令牌,并将其返回给客户端。

总结

现在,我们已经了解了如何在 StarBlog 项目中使用 JWT 来保护接口。通过使用 JWT,我们可以确保只有拥有有效 JWT 令牌的客户端才能访问受保护的资源。这将大大提高博客的安全性。

我希望这篇教程对你有帮助。如果你有任何问题,请随时留言。