目录
最近在做一个社团的网页以及管理系统项目,顺便借此机会在此记录自己每个功能实现的大致步骤.(需要具有.NET Core,EF Core等使用的相关知识的储备,以及会VS等基本软件的使用基础,这里对于基础内容不做讲解)
登录功能具体步骤如下:
- 建立Entity类,其中包括有Role角色,User用户以及UserRole用户角色类
- 配置好数据库连接
- 使用ORM框架生成数据表,我这里使用的是微软自己的EF Core
- 建立DTO层,用于解耦,同时也方便与前端进行交互
- 写接口(带有JWT认证)
接下来让我们正式开始吧.
一.创建实体类
1.1 安装Identity的Nugget包
为我们类库Entity安装Identity框架的包:
1.2 创建实体类
分别创建相关实体类,并继承Identity框架的相关类:
注意:继承类添加泛型是因为Identity的Id属性默认用的是Guid类型,以下:
最后别忘了在program.cs文件中注入服务,我这里考虑到后期项目庞大后注入服务会比较多,所以我采用单独文件夹写服务,最后统一注入:
1.3 配置数据库相关的连接
首先需要下载数据库所需要的相关包:
下载后在appsettings.json中添加数据库连接字符串:
再注入数据库连接服务:
在配置到相关的数据库初始化,主外键关系:
public class ApplicationDbContext : IdentityDbContext<User,Role,long>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
//设置表名
modelBuilder.Entity<User>().ToTable("User");
modelBuilder.Entity<Role>().ToTable("Role");
modelBuilder.Entity<UserRole>().ToTable("UserRole");
//指定键关系
modelBuilder.Entity<User>().HasMany<UserRole>().WithOne().HasForeignKey(x => x.UserId).OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Role>().HasMany<UserRole>().WithOne().HasForeignKey(x => x.RoleId).OnDelete(DeleteBehavior.Cascade);
//初始化数据
//1.添加角色
var adminRoleId = 1;
modelBuilder.Entity<Role>().HasData(new Role
{
Id = adminRoleId,
Name = "管理员",
CreationTime = DateTime.Now
});
//2.添加用户
var adminUserId = 1;
User adminUser = new User
{
Id = adminUserId,
UserName = "admin",
NormalizedUserName = "admin".ToUpper(),
FullName = "xxx",
Department = "",
Academy = "人工智能与大数据学院",
Major = "计算机科学与技术",
Class = "11班",
PhoneNumber = "1234567890",
Email = "1234567890@qq.com",
NormalizedEmail = "1234567890@qq.com".ToUpper(),
TwoFactorEnabled = false,
EmailConfirmed = true,
PhoneNumberConfirmed = false,
SecurityStamp = "Mecca",
CreationTime = DateTime.Now
};
PasswordHasher<User> ph = new PasswordHasher<User>();
adminUser.PasswordHash = ph.HashPassword(adminUser, "这里填密码");
modelBuilder.Entity<User>().HasData(adminUser);
//3.给用户加管理员身份
var UserRoleId = 1;
modelBuilder.Entity<UserRole>().HasData(new UserRole
{
Id = UserRoleId,
UserId = adminUserId,
RoleId = adminRoleId
});
}
}
最后使用Add-Migration InitDB和Update-database进行数据库迁移
此时,我们查看数据库发现,数据以完成迁移
1.4 建立DTO层
Dto层建立UserDto,RoleDto,Dto的属性跟实体类大致相同,具体根据你想要接收前端的哪些数据进行删除即可
public class UserDto
{
public long Id { get; set; }
/// <summary>
/// 学号
/// </summary>
public string UserName { get; set; }
/// <summary>
/// 姓名
/// </summary>
public string FullName { get; set; }
public string Academy { get; set; }
public string Major { get; set; }
public string Class { get; set; }
public string Department { get; set; }
public string Email { get; set; }
public string PhoneNumber { get; set; }
public DateTime CreationTime { get; set; } = DateTime.Now;
/// <summary>
/// 角色列表
/// </summary>
public List<RoleDto>? Roles { get; set; }
}
1.5 注入JWT服务
我们都知道,为了保护用户账号隐私,我们需要对用户信息进行鉴权,此时我们就需要使用JWT技术.
1. 安装所需要的包: Microsoft.AspNetCore.Authentication.JwtBearer
2.在appsettings中配置JWT信息
3.注入JWT服务
1.6 创建登录接口
namespace Club.API.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class LoginController : ControllerBase
{
private readonly SignInManager<User> _signInManager;
private readonly IConfiguration _configuration;
public LoginController(SignInManager<User> signInManager,IConfiguration configuration)
{
_signInManager = signInManager;
_configuration = configuration;
}
/// <summary>
/// 登录
/// </summary>
/// <param name="loginDto"></param>
/// <returns></returns>
[HttpPost("login")]
[AllowAnonymous]
public async Task<IActionResult> Login([FromBody] LoginDto loginDto)
{
//用户名和密码校验
var result = await _signInManager.PasswordSignInAsync(loginDto.UserName, loginDto.Password,false,false);
if (result.Succeeded)
{
//定义JWT的Playload部分
var claims = new[]
{
new Claim(ClaimTypes.Name,loginDto.UserName)
};
//生成token
var jwtBearer = _configuration.GetSection("Authentication").GetSection("JwtBearer");
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtBearer.GetValue<string>("SecurityKey")));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var securityToken = new JwtSecurityToken(
issuer: jwtBearer.GetValue<string>("Issuer"),
audience: jwtBearer.GetValue<string>("Audience"),
claims: claims,
expires: DateTime.Now.AddDays(1),
signingCredentials: creds
);
var token = new JwtSecurityTokenHandler().WriteToken(securityToken);
return Ok(token);
}
else
{
var responseResult = new ResponseResultDto();
responseResult.SetError("账号或密码错误");
return BadRequest(responseResult);
}
}
}
}
二.运行项目
运行项目,输入用户名和密码后正常返回Token,登录功能就此完成了.