C#基于jwt实现分布式登录

C#基于JWT实现分布式登录攻略

概述

JWT (JSON Web Token) 是一种用于在网络应用间传递身份信息的安全加密方式。它不需要在服务端存储token信息,使用时请求时发送jwt,服务端解析jwt和密钥进行验证即可,因此是一种轻量级的协议。在分布式架构下,使用JWT可以方便地实现服务间的身份验证。

本攻略将帮助你使用C#实现基于JWT的分布式登录。

步骤

第一步:安装依赖

JWT需要使用依赖包System.IdentityModel.Tokens.Jwt,使用Nuget进行安装:

Install-Package System.IdentityModel.Tokens.Jwt -Version 5.6.0

第二步:定义用户和用户服务

以下为一个简单的用户模型:

public class User
{
    public string Username { get; set; }
    public string Password { get; set; }
}

以下为一个简单的用户服务模型:

public interface IUserService
{
    User Authenticate(string username, string password);
}

你可以使用任何你喜欢的用户和用户服务模型,下面的示例中我们将使用以上提供的模型。

第三步:定义数据源

在我们的示例中,我们使用了一个静态变量作为我们的数据源,如下所示:

public class UserService : IUserService
{
    // 用于演示的数据源
    private List<User> _users = new List<User>
    {
        new User { Username = "admin", Password = "admin" },
        new User { Username = "test", Password = "test" }
    };

    public User Authenticate(string username, string password)
    {
        var user = _users.SingleOrDefault(u => u.Username == username && u.Password == password);

        // 用户不存在或密码错误
        if (user == null)
            return null;

        // 验证成功,返回用户信息
        return user;
    }
}

在一个实际的应用中,你需要从数据库或其他数据源中检索并验证用户信息,而不是像本示例那样使用静态变量。

第四步:定义JWT Token以及过期时间

为了加强token的安全性,我们需要定义一个key来验证token的有效性。

在本示例中,假设我们已经定义好了jwt security key:

private readonly byte[] _secretKey = Encoding.UTF8.GetBytes("thisIsMyJwtSecurityKey");

在此之后,我们需要定义JWT Token以及过期时间:

private string GenerateJwtToken(User user)
{
    var tokenHandler = new JwtSecurityTokenHandler();
    var key = _secretKey;

    var tokenDescriptor = new SecurityTokenDescriptor
    {
        Subject = new ClaimsIdentity(new Claim[]
        {
            new Claim(JwtRegisteredClaimNames.Sub, user.Username),
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
        }),
        Expires = DateTime.UtcNow.AddHours(1),
        SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
    };

    var token = tokenHandler.CreateToken(tokenDescriptor);

    return tokenHandler.WriteToken(token);
}

在此示例中,我们使用了SymmetricSecurityKeyHmacSha256Signature,但是你也可以使用其他的签名算法。

第五步:登录验证

在我们的用户服务中,我们定义了一个Authenticate方法。我们需要在此方法中完成身份验证并输出JWT Token。

在此之后,每次鉴权时,需要将JWT Token附加在HTTP请求标头上。

以下是详细的代码实现:

public class UserController : ControllerBase
{
    private readonly IUserService _userService;
    private readonly byte[] _secretKey = Encoding.UTF8.GetBytes("thisIsMyJwtSecurityKey");

    public UserController(IUserService userService)
    {
        _userService = userService;
    }

    [HttpPost("login")]
    public IActionResult Login([FromBody] User userParam)
    {
        // 身份验证
        var user = _userService.Authenticate(userParam.Username, userParam.Password);

        if (user == null)
            return BadRequest(new { message = "用户名或密码错误。" });

        // 创建jwt token
        var tokenString = GenerateJwtToken(user);

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

    [Authorize]
    [HttpGet("test")]
    public IActionResult Test()
    {
        return Ok("身份验证已通过。");
    }

    // 生成 jwt token
    private string GenerateJwtToken(User user)
    {
        var tokenHandler = new JwtSecurityTokenHandler();
        var key = _secretKey;

        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(new Claim[]
            {
                new Claim(JwtRegisteredClaimNames.Sub, user.Username),
                new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
            }),
            Expires = DateTime.UtcNow.AddHours(1),
            SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
        };

        var token = tokenHandler.CreateToken(tokenDescriptor);

        return tokenHandler.WriteToken(token);
    }
}

在此示例中,我们定义了一个Login方法和一个Test方法。当用户成功通过Login方法时,将返回JWT Token。此后,我们可以使用Test方法进行身份验证。HTTP请求应该附带一个标头——Authorization: Bearer <token>,其中<token>是在Login方法调用时获取到的JWT Token。

示例1:在ASP.Net Core中使用JWT验证身份

以下是一个具体的ASP.Net Core应用场景,其中代码提供了一个可用的控制器:

public class UserController : ControllerBase
{
    private readonly IConfiguration _configuration;

    public UserController(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    [HttpPost("login")]
    public IActionResult Login([FromBody] User user)
    {
        if (user == null)
        {
            return BadRequest("Invalid client request");
        }

        if (user.Username == "test" && user.Password == "test")
        {
            var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["SecretKey"]));
            var signinCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);

            var tokeOptions = new JwtSecurityToken(
                issuer: "http://localhost:5000",
                audience: "http://localhost:5000",
                claims: new List<Claim>(),
                expires: DateTime.Now.AddSeconds(30),
                signingCredentials: signinCredentials
            );

            var tokenString = new JwtSecurityTokenHandler().WriteToken(tokeOptions);
            return Ok(new { Token = tokenString });
        }

        return Unauthorized();
    }

    [HttpGet("{id}")]
    public IActionResult Get(int id)
    {
        var currentUser = HttpContext.User;

        var result = $"Your id is {id} and you are {currentUser.Identity.Name}.";
        return Ok(result);
    }
}

以上示例中,我们首先定义了一个Login方法,其中完成了用户验证并生成了JWT Token。而对于其他需要身份验证的方法,使用了ASP.Net Core默认的[Authorize]验证。

示例2:在WPF中使用JWT验证身份

以下示例是一个WPF应用中使用JWT进行身份验证的示例。我们使用JWT Token作为HTTP请求标头的Authorization参数。

private void SignInButton_Click(object sender, RoutedEventArgs e)
{
     var client = new WebClient();

    try
    {
        client.Headers.Add("authorization", "Bearer " + GetJwtToken());
        var result = client.DownloadString(_url + "/api/values");

        MessageBox.Show(result, "Success");
    }
    catch (WebException ex)
    {
        MessageBox.Show(ex.Message, "Error");
    }
}

private string GetJwtToken()
{
    var tokenHandler = new JwtSecurityTokenHandler();
    var key = Encoding.ASCII.GetBytes(_secretKey);
    var tokenDescriptor = new SecurityTokenDescriptor
    {
        Issuer = "issuer",
        Expires = DateTime.UtcNow.AddHours(_tokenDurationHours),
        SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key),
                            SecurityAlgorithms.HmacSha256Signature),
    };
    var token = tokenHandler.CreateToken(tokenDescriptor);
    var tokenString = tokenHandler.WriteToken(token);

    return tokenString;
}

结论

通过本攻略,我们学习了C#中基于JWT的分布式登录实现方法。在实际应用中,您可以将各种Web和桌面应用程序连接到您的身份验证服务,以实现高度安全的分布式身份验证。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#基于jwt实现分布式登录 - Python技术站

(0)
上一篇 2023年5月31日
下一篇 2023年5月31日

相关文章

  • 在多线程中调用winform窗体控件的实现方法

    在多线程中调用winform窗体控件是开发过程中常见的问题,因为在多线程场景下,是不允许直接操作UI控件的。下面是实现方法的完整攻略。 1. 合适的线程池 要在多线程中操作UI控件,第一步就要选用合适的线程池,它允许我们在不同的线程下执行不同的后台操作,同时又可以保留主线程的UI。以下是一个简单的示例: //线程池容量为5 ThreadPool.SetMax…

    C# 2023年5月15日
    00
  • C#委托delegate实例解析

    C#委托(delegate)实例解析 什么是委托 在C#中,委托是一种类型,它允许将方法作为参数传递给其他方法,类似于C++中的函数指针。 委托可以理解为一种类似于函数指针的东西,它通过引用方法来实现方法调用。委托包含一个方法的引用,通过它可以调用委托实例引用的方法。 委托的使用场景 多播委托:将多个方法绑定到同一个委托上,并调用这个委托就可以同时调用绑定的…

    C# 2023年6月8日
    00
  • ASP.NET返回上一页面的实现代码

    ASP.NET 是一种 Web 应用程序开发框架,提供很多丰富的 API,可以帮助我们轻松地开发 Web 应用程序。返回上一页面也是 ASP.NET 中非常常见的一个需求,本文将为您介绍如何实现 ASP.NET 返回上一页面的实现代码。 方法一:使用浏览器提供的返回功能 在 ASP.NET 中,我们可以使用浏览器提供的返回功能,让用户返回到上一页面。ASP.…

    C# 2023年5月31日
    00
  • C#编程实现Excel文档中搜索文本内容的方法及思路

    C#编程实现Excel文档中搜索文本内容的方法及思路 在 C# 编程中,实现搜索 Excel 文档中的文本内容是一个常见的需求。本文将介绍如何使用 C# 进行 Excel 文档的搜索文本内容,并附带两个示例说明。 思路 实现搜索 Excel 文档中的文本内容,可以采用以下步骤: 打开需要搜索的 Excel 文档。 遍历 Excel 文档中的所有单元格,查找包…

    C# 2023年6月8日
    00
  • C#利用VS中插件打包并发布winfrom程序

    下面我将为您详细讲解“C#利用VS中插件打包并发布winfrom程序”的完整攻略。 1. 安装插件 首先,您需要在Visual Studio中安装一个名为“Visual Studio Installer Projects”的插件。该插件可在Visual Studio扩展市场中免费下载。安装完成后,重启Visual Studio以使插件生效。 2. 创建安装包…

    C# 2023年5月15日
    00
  • Asp.net,C# 加密解密字符串的使用详解

    Asp.net,C# 加密解密字符串的使用详解 在Asp.net应用程序中,我们经常需要使用加密、解密字符串的操作,例如:在网站的用户注册、登录、密码找回等场景下,为了保障用户信息的安全,在将敏感数据存储到数据库中时,一般会使用加密算法对数据进行加密,以避免其被恶意窃取或篡改。本文将详细介绍Asp.net,C#加密解密字符串的使用方法。 Asp.net,C#…

    C# 2023年5月31日
    00
  • .NET Core自定义配置文件

    在本攻略中,我们将详细讲解.NET Core自定义配置文件的实现方法,并提供两个示例说明。 创建配置文件:首先,我们需要创建一个配置文件。我们可以使用JSON、XML或INI等格式来创建配置文件。例如,我们可以创建一个名为appsettings.json的JSON格式的配置文件,内容如下: { "MyConfig": { "Na…

    C# 2023年5月16日
    00
  • c#判断字符是否为中文的三种方法分享(正则表达式判断)

    当我们需要实现c#中判断一个字符是否为中文时,可以运用以下三种方法进行判断: 1. Unicode码判断法 Unicode码代表着一个全球通用的编码标准,它为每个字符分配了一个唯一的标识。 中文的Unicode编码范围为 4E00 ~ 9FFF,因此可以通过以下代码实现中文判断: public static bool IsChinese(char c) { …

    C# 2023年6月8日
    00
合作推广
合作推广
分享本页
返回顶部