net core mvc6使用jwt实现简单的登录

  1. 创建一个新的.NET Core Web应用程序项目。在创建项目时,选择MVC模板。

  2. 在项目中添加Microsoft.AspNetCore.Authentication.JwtBearer包:

在Visual Studio中,可以通过NuGet包管理器添加这个包:Tools > NuGet Package Manager > Manage NuGet Packages for Solution。
在NuGet 包管理器中搜索Microsoft.AspNetCore.Authentication.JwtBearer,选择安装。

可以通过以下命令在CLI中添加该包:

dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

  1. 在appsettings.json文件中添加JWT配置项:
"JWTSetting": {
    "Issuer": "MyIssuer",
    "Audience": "MyAudience",
    "SecurityKey": "MySecurityKey",
    "ExpireMinutes": 30
}

在这个样例中,我们为Issuer和Audience分别设置了"MyIssuer"和"MyAudience",设定了一个安全的机密SecurityKey,以及设置了一个过期时间(ExpireMinutes)。您可以根据您自己的需求调整这些选项。

  1. 添加JWT配置,打开Program.cs文件并添加以下代码段到Main方法中:
var builder = WebApplication.CreateBuilder(args);
var configuration = builder.Configuration;
var jwtOptions = new JWTSetting();
configuration.GetSection("JWTSetting").Bind(jwtOptions);

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options =>
                {
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuer = true,
                        ValidateAudience = true,
                        ValidateLifetime = true,
                        ValidateIssuerSigningKey = true,
                        ValidIssuer = jwtOptions.Issuer,
                        ValidAudience = jwtOptions.Audience,
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtOptions.SecurityKey))
                    };
                });

这段代码使用AddAuthentication()和AddJwtBearer()方法来注册JWT服务。在AddJwtBearer()调用中,我们可以传入一个TokenValidationParameters对象,用于验证JWT的有效性。JWT的有效性取决于密钥、签发人、受众、过期时间和签名的有效性。

在这个样例中,我们通过appSettings对象读取了配置文件中的JWTSetting部分(即JWT的配置项),然后使用Bind方法将这些值绑定到JWTSetting对象中。最后,我们配置了验证JWT的选项

  1. 添加JWT生成器,打开Startup.cs文件并添加以下代码段到ConfigureServices方法中:
//添加JWT生成器服务
services.AddSingleton<IJwtGenerator, JwtGenerator>();

在这个步骤中,我们注册了一个IJwtGenerator接口的实例,并将其设置为单例模式。IJwtGenerator是一个接口,用于生成JWT令牌。

  1. 创建一个JwtGenerator类实现IJwtGenerator接口,在接口中实现生成JWT令牌的方法:
    
public interface IJwtGenerator {
    string GenerateToken(User user);
}
    
public class JwtGenerator: IJwtGenerator {
    private readonly IConfiguration config;
    public JwtGenerator(IConfiguration config) {
        this.config = config;
    }
    public string GenerateToken(User user) {
        var tokenHandler = new JwtSecurityTokenHandler();
        var key = Encoding.ASCII.GetBytes(config["JWTSetting:SecurityKey"]);
        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(double.Parse(config["JWTSetting:ExpireMinutes"])),
            SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
        };
        var token = tokenHandler.CreateToken(tokenDescriptor);
        return tokenHandler.WriteToken(token);
    }
}
  1. 在您的控制器中,使用[Authorize]属性限制访问。例如:
[AllowAnonymous]
[HttpPost]
public async Task<ActionResult<string>> Login([FromBody] LoginDto loginDto)
{
    var user = await _userManager.FindByNameAsync(loginDto.UserName);
    if (user != null && await _userManager.CheckPasswordAsync(user, loginDto.Password))
    {
        var token = _jwtGenerator.GenerateToken(user);
        return Ok(token);
    }
    return Unauthorized();
}

[Authorize]
[HttpGet]
public async Task GetSomething() {
    //your action code
}

此时,只有经过身份验证并得到授权的用户才能访问您的控制器操作。

在前端代码中,需要创建一个登录页面,以便用户可以输入用户名和密码进行身份验证。在用户单击“登录”按钮时,需要向服务器发送HTTP POST请求,以便验证用户的身份并获取JWT令牌。如果身份验证成功,则将JWT令牌保存在本地存储中,并将用户重定向到受保护的页面。如果身份验证失败,则应显示错误消息。

以下是一个简单的登录页面的示例代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Login</title>
</head>
<body>
    <h1>Login</h1>
    <form id="login-form">
        <div>
            <label for="username">Username:</label>
            <input type="text" id="username" name="username" required>
        </div>
        <div>
            <label for="password">Password:</label>
            <input type="password" id="password" name="password" required>
        </div>
        <button type="submit">Login</button>
    </form>
    <div id="error-message" style="display: none; color: red;"></div>
    <script>
        var form = document.getElementById('login-form');
        var errorMessage = document.getElementById('error-message');
        form.addEventListener('submit', function(event) {
            event.preventDefault();
            var username = document.getElementById('username').value;
            var password = document.getElementById('password').value;
            var xhr = new XMLHttpRequest();
            xhr.open('POST', '/api/login', true);
            xhr.setRequestHeader('Content-Type', 'application/json');
            xhr.onreadystatechange = function() {
                 if (xhr.status === 200) {
                        var response = JSON.parse(xhr.responseText);
                        localStorage.setItem('jwt', response.token);
                        window.location.href = '/protected-page.html';
                    } else {
                        errorMessage.textContent = 'Invalid username or password.';
                        errorMessage.style.display = 'block';
                    }
            };
            xhr.send(JSON.stringify({username: username, password: password}));
        });
    </script>
</body>
</html>
posted @ 2023-03-23 19:43  红泥巴煮雪  阅读(444)  评论(0编辑  收藏  举报