net core mvc6使用jwt实现简单的登录
-
创建一个新的.NET Core Web应用程序项目。在创建项目时,选择MVC模板。
-
在项目中添加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
- 在appsettings.json文件中添加JWT配置项:
"JWTSetting": {
"Issuer": "MyIssuer",
"Audience": "MyAudience",
"SecurityKey": "MySecurityKey",
"ExpireMinutes": 30
}
在这个样例中,我们为Issuer和Audience分别设置了"MyIssuer"和"MyAudience",设定了一个安全的机密SecurityKey,以及设置了一个过期时间(ExpireMinutes)。您可以根据您自己的需求调整这些选项。
- 添加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的选项
- 添加JWT生成器,打开Startup.cs文件并添加以下代码段到ConfigureServices方法中:
//添加JWT生成器服务
services.AddSingleton<IJwtGenerator, JwtGenerator>();
在这个步骤中,我们注册了一个IJwtGenerator接口的实例,并将其设置为单例模式。IJwtGenerator是一个接口,用于生成JWT令牌。
- 创建一个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);
}
}
- 在您的控制器中,使用[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>