• 从零开始Blazor Server(4)--登录系统


    说明

    上一篇文章中我们添加了Cookie授权,可以跳转到登录页了。但是并没有完成登录,今天我们来完成它。


    我们添加Cookie授权的时候也说了,这套跟MVC一模一样,所以我们登录也是跟MVC一模一样。有个小区别是必须使用MVC去登录,Blazor本身是登录不了的。

    添加Controller支持

    Program.cs中添加:

    builder.Services.AddControllers().AddInject();

    这里的.AddInject()是添加Furion的支持,我们后面要用到的动态Controller就是需要添加这个。另外.AddInject()自带了Swagger,如果不想要,需要使用.AddInjectBase()

    app.UseInject();

    需要添加Swagger支持的话需要将app.UseInjectBase();这里改为app.UseInject();


    最后别忘了添加

    app.MapDefaultControllerRoute();

    将Controller的路由加上去。

    编写LoginController

    public class LoginController: IDynamicApiController
    {
        public async Task<object> Post([FromBody]LoginVo loginVo)
        {
            if (string.IsNullOrEmpty(loginVo.UserName))
            {
                return new { code = 50000, message = "用户名不能为空" };
            }
            if (string.IsNullOrEmpty(loginVo.Password))
            {
                return new { code = 50000, message = "密码不能为空" };
            }
    
            var password = MD5Encryption.Encrypt(loginVo.Password);
            var user = await UserEntity.Where(x =>
                x.UserName == loginVo.UserName && x.Password == password).Include(x => x.Role).FirstAsync();
            if (user != null)
            {
                var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
                identity.AddClaim(new Claim(ClaimTypes.Name, user.UserName!));
                identity.AddClaim(new Claim(ClaimTypes.Role, user.Role!.Name!));
                await Furion.App.HttpContext.SignInAsync(new ClaimsPrincipal(identity), new AuthenticationProperties(){IsPersistent = true, ExpiresUtc = loginVo.RememberMe? DateTimeOffset.Now.AddDays(5): DateTimeOffset.Now.AddMinutes(30)});
    
                return new { code = 20000, message = "登录成功" };
            }
            return new { code = 50000, message = "用户名或密码错误" };
        }
    }
    折叠

    其中用的LoginVo为

    public class LoginVo
    {
        public string? UserName { get; set; }
    
        public string? Password { get; set; }
    
        public bool RememberMe { get; set; }
    }

    这里我们使用var user = await UserEntity.Where(x => x.UserName == loginVo.UserName && x.Password == password).Include(x => x.Role).FirstAsync();

    去数据库里查询是否存在这个用户名密码的用户


    然后创建一个Claim,我这里把UserNameRoleName放进去了,为了后面好显示。


    最后就是HttpContext.SignIn,这个也是登录的标准路子。

    Login.razor

    Login.razor我们直接照搬了BootstrapAdmin的登录样式,搬运一下,懒得自己写了。这里只说关键代码部分。


    首先,因为我们说过,登录需要使用MVC的方式,所以这里需要使用浏览器发送Ajax请求的方式来登录。

    这里我们使用BootstrapBlazor自带的AJAX组件来处理。


    首先在Login.razor中添加组件进来。


    然后使用

    var ajaxOption = new AjaxOption
            {
                Url = "/api/login",
                Data = LoginVo
            };
            var str = await AjaxService.GetMessage(ajaxOption);

    使用POST发送LoginVo到/api/login

    这个str就是返回的结果。


    如果str是空的,或者code不是上面返回的20000,即登录成功的话,我们就使用飘窗报错。成功我们就跳转。

    这里注意一下,跳转的时候一定不能用Blazor的NavigationManager,因为我们必须刷新一次浏览器,服务端才能拿到对应的Cookie,所以这里还是使用Ajax组件的Goto去跳转,这种跳转实际上是浏览器刷新,会重走一次MVC的逻辑。

    这样我们的登录就写好了。尝试输入用户名密码都是Admin(我们在DbExtension初始化的默认用户)。应该可以登录成功,输入别的话应该会报失败。


    源码在github:https://github.com/j4587698/BlazorLearn,分支为lesson4

  • 相关阅读:
    大型语言模型的语义搜索(二):文本嵌入(Text Embeddings)
    Window10 安装 Lua
    微信小程序uniapp+django+python的酒店民宿预订系统ea9i3
    【C语言】字符串函数和内存函数的使用及其模拟实现
    【开源】基于SpringBoot的衣物搭配系统的设计和实现
    vue-router配置
    Mybatis——Mybatis入门项目从创建到完成的完整过程【单表的增删改查】
    window10下安装docker教程
    基于Java的企业门户管理系统设计与实现(源码+lw+部署文档+讲解等)
    基于复旦微的FMQL45T900全国产化ARM核心模块(100%国产化)
  • 原文地址:https://www.cnblogs.com/j4587698/p/16539020.html