目录
一、创建项目
创建ASP.NET Core Web项目(MVC),我用的是VS2022
这是创建好的项目
下载好本项目需要用到的包,默认下载最新版
二、数据库设计
1、MySQL数据库创建
我这边选的是MySQL数据库作为数据存储,有需要可以自行选择
在MySQL运行以下语句
CREATE TABLE Users_test (
Id INT PRIMARY KEY AUTO_INCREMENT,
Username VARCHAR(50) NOT NULL,
Password VARCHAR(50) NOT NULL,
Role VARCHAR(20) NOT NULL
);
INSERT INTO Users_test (Username, Password, Role) VALUES ('admin', 'admin123', 'Admin');
INSERT INTO Users_test (Username, Password, Role) VALUES ('user', 'user123', 'User');
创建好之后是这样的
2、模型创建
在Model文件夹下面创建User.cs
里面的 [SugarTable("User_test")],SugarTable是SqlSugar里面的一个特性,User_test是数据库表名
using SqlSugar;
using System.ComponentModel.DataAnnotations;
namespace Logon_test.Models
{
/// <summary>
/// 用户表
/// </summary>
[SugarTable("Users_test")]
public class User
{
//主键
[Key]
public int Id { get; set; }
//用户名
[Required]
[StringLength(50)]
public string Username { get; set; }
//密码
[Required]
[StringLength(50)]
public string Password { get; set; }
//角色
[Required]
[StringLength(20)]
public string Role { get; set; }
}
}
3、数据访问层
配置SqlSugar和MySQL连接
新建Data文件夹,在Data文件夹下面新建ApplicationDbContext.cs这个是配置SqlSugar用的
using SqlSugar;
using System;
using Microsoft.Extensions.Configuration;
namespace Logon_test.Data
{
public class ApplicationDbContext
{
public SqlSugarClient Db { get; private set; }
public ApplicationDbContext(IConfiguration configuration)
{
Db = new SqlSugarClient(new ConnectionConfig()
{
ConnectionString = configuration.GetConnectionString("DefaultConnection"),
DbType = DbType.MySql,
IsAutoCloseConnection = true,
InitKeyType = InitKeyType.Attribute
});
Db.CodeFirst.InitTables(typeof(Models.User)); // Initialize User table
}
}
}
在appsettings.json中添加数据库连接字符串
server=localhost数据库地址,数据库在本地的跟我一样填就行
user id=youruser连接数据库的用户名
password=yourpassword连接数据库的密码
database=test数据库的名称
4、业务逻辑层
新建一个Services文件夹,在文件夹下面新建UserService.cs
把所有数据库访问语句都放在这里面,以便后续的调用
具体代码
using Logon_test.Models;
using SqlSugar;
using System.Linq;
namespace Logon_test.Service
{
public class UserService
{
private readonly SqlSugarClient _db;
public UserService(SqlSugarClient db)
{
_db = db;
}
/// <summary>
/// 登录查询
/// </summary>
/// <param name="username"></param>
/// <param name="password"></param>
/// <returns></returns>
public User Authenticate(string username, string password)
{
return _db.Queryable<User>().First(u => u.Username == username && u.Password == password);
}
/// <summary>
/// 注册新增
/// </summary>
/// <param name="user"></param>
public void Register(User user)
{
_db.Insertable(user).ExecuteCommand();
}
/// <summary>
/// 注册查询
/// </summary>
/// <param name="username"></param>
/// <returns></returns>
public bool UserExists(string username)
{
return _db.Queryable<User>().Any(u => u.Username == username);
}
}
}
三、WEB项目
1、创建web视图
创建一个Account文件夹,用来保存登录和注册视图
在Account目录下创建Login.cshtml
具体代码
@{
ViewData["Title"] = "登录";
}
<!DOCTYPE html>
<html>
<head>
<title>@ViewData["Title"]</title>
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
font-family: Arial, sans-serif;
background-color: #f0f0f0;
}
.login-container {
background-color: #fff;
padding: 20px;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
width: 300px;
text-align: center;
}
.login-container h2 {
margin-bottom: 20px;
color: #333;
}
.login-container label {
display: block;
text-align: left;
margin-bottom: 10px;
color: #555;
}
.login-container input[type="text"],
.login-container input[type="password"] {
width: calc(100% - 20px);
padding: 10px;
margin-bottom: 15px;
border: 1px solid #ccc;
border-radius: 3px;
font-size: 14px;
}
.login-container button {
width: 100%;
padding: 10px;
background-color: #007bff;
border: none;
color: #fff;
cursor: pointer;
border-radius: 3px;
font-size: 16px;
margin-top: 10px; /* 添加按钮与表单之间的间距 */
}
.login-container button:hover {
background-color: #0056b3;
}
.register-link {
display: block;
margin-top: 10px;
text-decoration: none;
color: #007bff;
}
.register-link:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div class="login-container">
<h2>登录</h2>
<form asp-action="Login" method="post">
<div>
<label>用户名:</label>
<input type="text" name="username" required />
</div>
<div>
<label>密码:</label>
<input type="password" name="password" required />
</div>
<button type="submit">登录</button>
</form>
<a href="~/Account/Register" class="register-link">注册</a>
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
</div>
</body>
</html>
现在创建注册视图,跟上面同样的操作,取名Register.cshtml
@{
ViewData["Title"] = "Register";
}
<!DOCTYPE html>
<html>
<head>
<title>@ViewData["Title"]</title>
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
font-family: Arial, sans-serif;
background-color: #f0f0f0;
}
.register-container {
background-color: #fff;
padding: 20px;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
width: 300px;
text-align: center;
}
.register-container h2 {
margin-bottom: 20px;
color: #333;
}
.register-container label {
display: block;
text-align: left;
margin-bottom: 10px;
color: #555;
}
.register-container input[type="text"],
.register-container input[type="password"],
.register-container select {
width: calc(100% - 20px);
padding: 10px;
margin-bottom: 15px;
border: 1px solid #ccc;
border-radius: 3px;
font-size: 14px;
}
.register-container button {
width: 100%;
padding: 10px;
background-color: #007bff;
border: none;
color: #fff;
cursor: pointer;
border-radius: 3px;
font-size: 16px;
}
.register-container button:hover {
background-color: #0056b3;
}
</style>
</head>
<body>
<div class="register-container">
<h2>注册</h2>
<form asp-action="Register" method="post">
<div>
<label>用户名:</label>
<input type="text" name="Username" required />
</div>
<div>
<label>密码:</label>
<input type="password" name="Password" required />
</div>
<div>
<label>角色:</label>
<select name="Role" required>
<option value="User">User</option>
<option value="Admin">Admin</option>
</select>
</div>
<button type="submit">注册</button>
</form>
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
</div>
</body>
</html>
创建Index.cshtm视图,这个作为我们登录之后跳转的页面
为了不影响判断,我先删除创建项目自动生成的视图,
删除完,在Home文件夹新建Index.cshtml
@{
ViewData["Title"] = "Home Page";
}
<!DOCTYPE html>
<html>
<head>
<title>@ViewData["Title"]</title>
<style>
html, body {
font-family: Arial, sans-serif;
background-color: #f0f0f0;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.content {
text-align: center;
}
.welcome-message {
margin-bottom: 20px;
font-size: 24px;
}
.username {
font-weight: bold;
color: #007bff;
}
.logout-button {
padding: 10px 20px;
background-color: #007bff;
color: #fff;
border: none;
border-radius: 3px;
cursor: pointer;
font-size: 16px;
text-decoration: none;
}
.logout-button:hover {
background-color: #0056b3;
}
</style>
</head>
<body>
<div class="content">
<h1>欢迎访问主页</h1>
@if (User.Identity.IsAuthenticated)
{
<p class="welcome-message">
你好,<span class="username">
@if (User.IsInRole("Admin"))
{
<span>管理员</span>
}
else if (User.IsInRole("User"))
{
<span>普通用户</span>
}
else
{
<span>未知角色</span>
}
</span>!
</p>
<form asp-action="Logout" method="post">
<button type="submit" class="logout-button">注销</button>
</form>
}
else
{
<p>请 <a href="/Account/Login">login</a> 重新登录</p>
}
</div>
</body>
</html>
2、创建控制器
创建一个账号控制器来处理登录和注册请求。
在Controllers文件下,创建AccountController控制器
using Logon_test.Models;
using Logon_test.Service;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
namespace Logon_test.Controllers
{
public class AccountController : Controller
{
private readonly UserService _userService;
public AccountController(UserService userService)
{
_userService = userService;
}
[HttpGet]
public IActionResult Login()
{
return View();
}
/// <summary>
/// 登录
/// </summary>
/// <param name="username"></param>
/// <param name="password"></param>
/// <returns></returns>
[HttpPost]
public async Task<IActionResult> Login(string username, string password)
{
var user = _userService.Authenticate(username, password);//查询用户
if (user != null)
{
// 创建用户的声明信息
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.Username),
new Claim(ClaimTypes.Role, user.Role)
};
// 创建身份信息
var claimsIdentity = new ClaimsIdentity(
claims, CookieAuthenticationDefaults.AuthenticationScheme);
// 设置认证Cookie的属性
var authProperties = new AuthenticationProperties
{
};
// 使用HttpContext.SignInAsync方法设置用户的认证信息
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
authProperties);
return RedirectToAction("Index", "Home");//跳转页面
}
ModelState.AddModelError(string.Empty, "登录失败,请检查用户名和密码!");
return View();
}
[HttpGet]
public IActionResult Register()
{
return View();
}
/// <summary>
/// 注册
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
[HttpPost]
public IActionResult Register(User user)
{
//用户是否被注册
if (_userService.UserExists(user.Username))
{
ModelState.AddModelError(string.Empty, "注册出错,用户已经注册过了!");
return View();
}
_userService.Register(user);
return RedirectToAction("Login");
}
}
}
3、设置启动配置
在根目录新建Startup.cs
using Longon_test.Data;
using Longon_test.Services;
using Microsoft.AspNetCore.Authentication.Cookies;
namespace Longon_test
{
public class Startup
{
/// <summary>
/// 读取配置信息
/// </summary>
/// <param name="configuration"></param>
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
/// <summary>
/// 注册服务
/// </summary>
/// <param name="services"></param>
public void ConfigureServices(IServiceCollection services)
{
///身份验证
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.Cookie.Name = "LogonApp.Cookie";// 设置认证Cookie的名称
options.Cookie.HttpOnly = true;//确保Cookie只能通过HTTP传输,不能通过客户端脚本访问
options.ExpireTimeSpan = TimeSpan.FromMinutes(60);//设置认证Cookie的过期时间为60分钟
options.LoginPath = "/Home/Login"; // 登录页面路径
options.AccessDeniedPath = "/Home/AccessDenied"; // 访问被拒绝页面路径
});
services.AddControllersWithViews();//启用MVC
services.AddSingleton<ApplicationDbContext>();//单例,数据库访问
services.AddSingleton<UserService>(provider =>
{
var context = provider.GetService<ApplicationDbContext>();
return new UserService(context.Db);
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//异常处理
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
//路由
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Account}/{action=Login}/{id?}");
});
}
}
}
修改Program.cs
using Longon_test;
namespace Logon_test
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}
3、修改
修改_Layout.cshtml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - Logon_test</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<link rel="stylesheet" href="~/Logon_test.styles.css" asp-append-version="true" />
</head>
<body>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container text-center">
<!-- 添加 text-center 类 -->
© 2024 - 登录系统
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>
修改 HomeController控制器
using Logon_test.Models;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
namespace Logon_test.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
return View();
}
/// <summary>
/// 注销
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<IActionResult> Logout()
{
// 清除当前用户的身份认证信息
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
// 清除任何之前登录时设置的临时信息
TempData.Clear();
return RedirectToAction("Login", "Account");
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}
四、效果
五、结言
该项目用的是.net core,ORM框架用的是SqlSugar,想要了解的可以百度,当然你们也可以选择用EF,效果是一样的,总的来说,该登录和注册功能实现还是很简单的,希望对你们有所帮助