使用标识框架对用户、角色进行操作时,需要先完成框架的搭建,操作参考文章:
案例1:创建用户和角色
判断角色是否存在,不存在则创建;判断用户是否存在,不存在则创建;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
namespace 鉴权与授权.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class DemoController : Controller
{
private readonly ILogger<DemoController> logger;
private readonly UserManager<User> userManager;
private readonly RoleManager<Role> roleManager;
public DemoController(ILogger<DemoController> logger, UserManager<User> userManager, RoleManager<Role> roleManager)
{
this.logger = logger;
this.userManager = userManager;
this.roleManager = roleManager;
}
[HttpPost]
public async Task<ActionResult<string>> TestAction()
{
//判断角色是否存在
bool roleExists = await roleManager.RoleExistsAsync("admin");
if (!roleExists)
{
Role role = new Role { Name = "admin" };
var r = await roleManager.CreateAsync(role);
if (!r.Succeeded)
{
return BadRequest(r.Errors);
}
}
//判断用户是否存在
User user = await userManager.FindByNameAsync("zhangsan");
if (user == null)
{
user = new User { UserName = "zhangsan", NiceName = "张三", Email = "[email protected]", EmailConfirmed = true };
var u = await userManager.CreateAsync(user, "123456");
if (!u.Succeeded)
{
return BadRequest(u.Errors);
}
var ur = await userManager.AddToRoleAsync(user, "admin");
if (!ur.Succeeded)
{
return BadRequest(ur.Errors);
}
}
return "ok";
}
}
}
程序执行结果:
案例2:处理登录请求
LoginRequest.cs
public record LoginRequest(string UserName,string Password);
控制器中的方法:
[HttpPost]
public async Task<ActionResult<string>> LoginAction(LoginRequest request)
{
string userName = request.UserName;
string password = request.Password;
var user = await userManager.FindByNameAsync(userName);
if (user == null)
{
return NotFound("用户名或密码错误");
}
bool isLock = await userManager.IsLockedOutAsync(user);
if (isLock)
{
return NotFound("用户名已被锁定");
}
var isSuccess = await userManager.CheckPasswordAsync(user, password);
if (isSuccess)
{
//重置错误次数
await userManager.ResetAccessFailedCountAsync(user);
return "用户名密码校验通过";
}
else
{
//错误次数+1
await userManager.AccessFailedAsync(user);
}
return NotFound("用户名或密码错误");
}
案例3:实现密码的重置
控制器中的方法:
/// <summary>
/// 重置密码前发送验证码
/// </summary>
/// <param name="userName">用户名</param>
/// <returns></returns>
[HttpPost]
public async Task<ActionResult> SendResetPasswordToken(string userName)
{
var user = await userManager.FindByNameAsync(userName);
if (user == null)
{
return BadRequest("用户不存在");
}
string token = await userManager.GeneratePasswordResetTokenAsync(user);
logger.LogInformation($"向邮箱{user.Email},发送验证码{token}");
return Ok();
}
执行结果:
根据用户名和验证码,重置密码
/// <summary>
/// 重置密码
/// </summary>
/// <param name="userName">用户名</param>
/// <param name="newPassword">密码</param>
/// <param name="token">验证码</param>
/// <returns></returns>
[HttpPost]
public async Task<ActionResult> UpdatePassword(string userName, string newPassword, string token)
{
var user = await userManager.FindByNameAsync(userName);
if (user == null)
{
return BadRequest("用户不存在");
}
var result = await userManager.ResetPasswordAsync(user, token, newPassword);
if (result.Succeeded)
{
//重置错误次数
await userManager.ResetAccessFailedCountAsync(user);
return Ok("密码重置成功");
}
else
{
return BadRequest("密码重置失败");
}
}
执行结果: