作者: ShiYu

  • 下次一定

    呜呜,我又来写日记啦

    今天玩的双人成行当个头图吧

    记得:

    • 洗脸
    • 化妆
    • 扎头发
  • 迟来的更新

    玖月-拾壹月

    好久没写日记啦,快来补一补这段时间的空白
    此情可待成追忆插图1
    刘兰婷
    你都不写我
    此情可待成追忆插图1
    刘兰婷
    我伤心了
    此情可待成追忆插图1
    刘兰婷
    以后
    此情可待成追忆插图1
    刘兰婷
    一天一更

    这一整个学期几乎都是在封校中度过的,我是八月二十七开的学,刚好是刘兰婷的生日,开学后的九月份,泰安的疫情还是比较好一些的,没有封校,但是济南的疫情好严重,刘兰婷线下开学也推迟啦。

    假期中计划的每个月见面一两次并没这么容易的实现,我们忽略了疫情封校的关键因素,呜呜。

    幸好,刘兰婷线上开学的时候,也就是九月十一号,中秋节过后,我们见面啦!但是今天到十二号也已经过去了74天了,这也是在一起以来见面间距最长的一次。

    中秋节后的见面,我居然没有写日记!!!罪过罪过

    九月十一日:泰安站,我来接刘兰婷啦!😍

    见面的时间总是过得很快,时间好像总是不够用的,一起躺着看甄嬛传,点上一堆外卖吃起来好像比在外面吃大餐更舒服。

    这个中秋节见面后没想到下一次的见面会这么远,直到今天,我们仍都被封在各自的学校。而下一次的见面可能是在期末之后的寒假了。😭

    圆圆的脑袋

    有点楞

    TA 无标准

    第一次在操场跑3.8公里,刘兰婷也有小牌牌啦!

    —2022年9月21日跑完

    创造101

    呜呜呜,女朋友居然带我看漂亮女孩综艺节目。

    —2022年10月26日开始

    沉默的真相

    呜呜我拉着刘兰婷看的悬疑剧,反正我觉得好看!

    —2022年11月2日开始

    打火机与公主裙

    呜呜呜,打火机太拽了,去监狱反省反省!

    —2022年11月14日开始

    双人成行

    终于秋促打折啦,和刘兰婷一起双人成行!

    —2022年11月23日入库

    从22年的6月10日到现在也有了168天,但是我们见面的时间不到其中的五分之一,每一次的刚见面的开始感觉好像还有好多时间,分离前又感觉时间的短促。

    2022年的冬天我们可以在济南看一场雪嘛!

    2022年的最后一天我们可以在一起迎接2023年的到来嘛!

  • wsl2下docker安装MySQL

    首先拉取MySQL镜像:docker pull mysql

    如图镜像拉取成功

    启动镜像生成容器,需要设置变量MYSQL_ROOT_PASSWORD,为默认root密码

    启动完成

    这样就可以链接成功啦!

  • Blazor Service 身份验证

    Blazor 是微软的新型的web开发方案,用来做全栈开发真是太爽了。

    之前用 Blazor 做了几个小应用,但是一直没有去做身份验证系统,之前也没有ASP.NET的基础,C#也是最近学的,而且重要的是,网上居然几乎没有相关的资料,于是咱就结合网上的一些信息和微软的官方文档(微软的文档是我见过最好的文档了)做了一个身份鉴权的小Demo。

    首先创建 Blazor Service 项目:

    然后在项目的目录下创建Auth目录存放鉴权的基础设施

    Provider 是鉴权的服务提供者

    UserAccount 是用户账号模型

    UserAccountService 是用户账号服务

    UserSession 是用户 session 数据模型

    在 Provider 下写自定义的基础认证服务,这里使用的session的形式做鉴权认证。

    using Microsoft.AspNetCore.Components.Authorization;
    using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;
    using System.Security.Claims;
    
    namespace BSAuth.Auth
    {
        public class Provider : AuthenticationStateProvider
        {
            private readonly ProtectedSessionStorage _sessionStorage;
            private readonly ClaimsPrincipal _anonymous = new ClaimsPrincipal(new ClaimsIdentity());
            public Provider(ProtectedSessionStorage sessionStorage)
            {
                _sessionStorage = sessionStorage;
            }
    
            public override async Task<AuthenticationState> GetAuthenticationStateAsync()
            {
                try
                {
                    var userSessionStorageResult = await _sessionStorage.GetAsync<UserSession>("UserSession");
                    var userSession = userSessionStorageResult.Success ? userSessionStorageResult.Value : null;
                    if (userSession == null)
                    {
                        return await Task.FromResult(new AuthenticationState(_anonymous));
                    }
                    var claimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>
                    {
                        new Claim(ClaimTypes.Name,userSession.UserName),
                        new Claim(ClaimTypes.Role,userSession.Role)
                    }, "customAuth")); ;
                    return await Task.FromResult(new AuthenticationState(claimsPrincipal));
                }
                catch
                {
                    return await Task.FromResult(new AuthenticationState(_anonymous));
                }
    
            }
            public async Task UpdateAuthState(UserSession userSession)
            {
                ClaimsPrincipal claimsPrincipal;
                if (userSession is not null)
                {
                    await _sessionStorage.SetAsync("UserSession", userSession);
                    claimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>
                    {
                        new Claim(ClaimTypes.Name,userSession.UserName),
                        new Claim(ClaimTypes.Role,userSession.Role)
                    }));
                }
                else
                {
                    await _sessionStorage.DeleteAsync("UserSession");
                    claimsPrincipal = _anonymous;
                }
                NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(claimsPrincipal)));
            }
        }
    }
    

    创建 UserSession 模型和 UserAccount 模型

    namespace BSAuth.Auth
    {
        public class UserSession
        {
            public string UserName { get; set;}
            public string Role { get; set;}
        }
    }
    
    namespace BSAuth.Auth
    {
        public class UserAccount
        {
            public string UserName { get; set; }
            public string Password { get; set; }
            public string Role { get; set; }
        }
    }
    

    然后建立账户系统服务,这里Demo用的内存数据模拟,实际应该使用数据库

    namespace BSAuth.Auth
    {
        public class UserAccountService
        {
            private List<UserAccount> _user;
            public UserAccountService()
            {
                _user = new List<UserAccount>
                {
                    new UserAccount{UserName="张三",Password="zs",Role="admin"},
                    new UserAccount{UserName="李四",Password="ls",Role="user"}
                };
            }
            public UserAccount? GetByUserName(string userName)
            {
                return _user.FirstOrDefault(x => x.UserName == userName);
            }
        }
    }
    

    然后鉴权服务就做好啦,下面要将这些服务注入到项目中。

    在Program里依赖注入的形式注入基础认证服务和账号服务

    接下来在App.razor下使用认证视图标签

    一个简单的登录页面示例;

    @page "/login"
    @inject IJSRuntime ij
    @using BSAuth.Auth
    @inject UserAccountService userAccountService
    @inject AuthenticationStateProvider authStateProvider
    @inject NavigationManager navigation
    <h3>Login</h3>
    <input @bind="UserName" type="text"/>
    <input @bind="PassWord" type="password"/>
    <button @onclick="LoginAuth">登录</button>
    @code {
        string UserName { get; set; }
        string PassWord{ get; set; }
        private async Task LoginAuth()
        {
            var userAccount = userAccountService.GetByUserName(UserName);
            if(userAccount is  null || userAccount.Password != PassWord)
            {
                await ij.InvokeVoidAsync("alert", "登录失败");
                return;
            }
            var provider = (Provider)authStateProvider;
            await provider.UpdateAuthState(new UserSession
                {
                    UserName = userAccount.UserName,
                    Role = userAccount.Role
                });
            await ij.InvokeVoidAsync("alert", "登录成功");
            navigation.NavigateTo("/");
        }
    }
    

    然后可以在需要鉴权的视图资源下使用 AuthorizeView 组件

    具体使用方式请参照微软文档:ASP.NET Core Blazor 身份验证和授权 | Microsoft Learn