🫓05 ASP.NET Core高级
00 分钟
2023-12-19
2023-12-19
type
status
date
slug
summary
tags
category
icon
password

Identity框架

Authentication与Authorization
1、Authentication对访问者的用户身份进行验证,“用户是否登录成功”。
2、Authorization验证访问者的用户身份是否有对资源访问的访问权限,“用户是否有权限访问这个地址”。
标识(Identity)框架
1、标识(Identity)框架:采用基于角色的访问控制(Role-Based Access Control,简称RBAC)策略,内置了对用户、角色等表的管理以及相关的接口,支持外部登录、2FA等。
2、标识框架使用EF Core对数据库进行操作,因此标识框架支持几乎所有数据库。
Identity框架使用说明

JWT(Json Web Token)

1、JWT把登录信息(也称作令牌)保存在客户端。
2、为了防止客户端的数据造假,保存在客户端的令牌经过了签名处理,而签名的密钥只有服务器端才知道,每次服务器端收到客户端提交过来的令牌的时候都要检查一下签名。
3、基于JWT如何实现“登录”。
.NET Core中JWT的基本使用
.NET Core中JWT的封装
让Swagger中调试带JWT的请求
解决JWT无法提前撤回的难题
JWT的缺点
1、到期前,令牌无法被提前撤回。什么情况下需要撤回?用户被删除了、禁用了;令牌被盗用了;单设备登录。
2、需要JWT撤回的场景用传统Session更合适。
3、如果需要在JWT中实现,思路:用Redis保存状态,或者用refresh_token+access_token机制等。
思路:
在用户表中增加一个整数类型的列JWTVersion,代表最后一次发放出去的令牌的版本号;每次登录、发放令牌的时候,都让JWTVersion的值自增,同时将JWTVersion的值也放到JWT令牌的负载中;当执行禁用用户、撤回用户的令牌等操作的时候,把这个用户对应的JWTVersion列的值自增;当服务器端收到客户端提交的JWT令牌后,先把JWT令牌中的JWTVersion值和数据库中JWTVersion的值做一下比较,如果JWT令牌中JWTVersion的值小于数据库中JWTVersion的值,就说明这个JWT令牌过期了。
实现:
1、为用户实体User类增加一个long类型的属性JWTVersion。
2、修改登录并发放令牌的代码,把用户的JWTVersion属性的值自增,并且把JWTVersion的值写入JWT令牌。
3、编写一个操作筛选器,统一实现对所有的控制器的操作方法中JWT令牌的检查操作。把JWTValidationFilter注册到Program.cs中MVC的全局筛选器中。
优化:
每一次客户端和Controller的交互的时候,检查JWTVersion的筛选器都要查询数据库,性能太低,可以用缓存进行优化。

托管服务的基本使用

托管服务简介
1、场景,代码运行在后台。比如服务器启动的时候在后台预先加载数据到缓存,每天凌晨3点把数据导出到备份数据库,每隔5秒钟在两张表之间同步一次数据。
2、托管服务实现IHostedService接口,一般编写从BackgroundService继承的类。
测试:延迟若干秒再读取文件,再延迟,再输出。
3、services.AddHostedService<DemoBgService>();
托管服务的异常问题
1、从.NET 6开始,当托管服务中发生未处理异常的时候,程序就会自动停止并退出。可以把HostOptions.BackgroundServiceExceptionBehavior设置为Ignore,程序会忽略异常,而不是停止程序。不过推荐采用默认的设置,因为“异常应该被妥善的处理,而不是被忽略”。
2、要在ExecuteAsync方法中把代码用try……catch包裹起来,当发生异常的时候,记录日志中或发警报等。
托管服务中使用DI
1、托管服务是以单例的生命周期注册到依赖注入容器中的。因此不能注入生命周期为范围或者瞬态的服务。
比如注入EF Core的上下文的话,程序就会抛出异常。
2、可以通过构造方法注入一个IServiceScopeFactory服务,它可以用来创建一个IServiceScope对象,这样我们就可以通过IServiceScope来创建短生命周期的服务了。记得在Dispose中释放IServiceScope。

FluentValidation的基本使用 数据校验

FluentValidation + DI

什么是WebSocket 、SignalR

服务器向客户端发送数据
1、需求:Web聊天;站内通知。
2、传统HTTP:只能客户端主动发送请求。
3、传统方案:长轮询(Long Polling)。
WebSocket
1、WebSocket基于TCP协议,支持二进制通信,双工通信。
2、性能和并发能力更强。
3、WebSocket独立于HTTP协议,不过我们一般仍然把WebSocket服务器端部署到Web服务器上,因为可以借助HTTP协议完成初始的握手(可选),并且共享HTTP服务器的端口(主要)。
SignalR
1、ASP.NET Core SignalR(以下简称SignalR),是.NET Core平台下对WebSocket的封装。
2、Hub(集线器),数据交换中心。

SignalR基本使用

SignalR的协议协商
1、SignalR支持多种服务器推送方式:Websocket、Server-Sent Events、长轮询。默认按顺序尝试。
2、F12查看协商过程。
3、websocket和HTTP是不同的协议,为什么能用同一个端口。
4、在【开发人员工具】的【网络】页签中看WebSocket通信过程。
问题:
1、集群中协议协商的问题:“协商”请求被服务器A处理,而接下来的WebSocket请求却被服务器B处理。
2、解决方法:粘性会话和禁用协商。
3、 “粘性会话”(Sticky Session):把来自同一个客户端的请求都转发给同一台服务器上。缺点:因为共享公网IP等造成请求无法被平均的分配到服务器集群;扩容的自适应性不强。
4、“禁用协商”:直接向服务器发出WebSocket请求。WebSocket连接一旦建立后,在客户端和服务器端直接就建立了持续的网络连接通道,在这个WebSocket连接中的后续往返WebSocket通信都是由同一台服务器来处理。缺点:无法降级到“服务器发送事件”或“长轮询”,不过不是大问题。
SignalR的分布式部署
SignalR身份认证
1、目前SignalR问题:谁都能连。讲JWT方案。
2、配置SigningKey、ExpireSeconds。创建配置类JWTOptions。
3、NuGet:Microsoft.AspNetCore.Authentication.JwtBearer
SignalR向部分客户端发消息
筛选客户端
1、客户端筛选的3个参数:ConnectionId、组和用户Id(它对应ClaimTypes.NameIdentifier的Claim)。
2、Hub的Groups属性为IGroupManager属性,可以对组成员进行管理。查看类型的成员。
3、Hub的Clients属性为IHubCallerClients类型,可以对连接到当前集线器的客户端进行筛选。查看类型的成员。
4、IClientProxy类型。无法知道具体有哪些客户端调用SendAsync()方法向筛选的客户端发送消息。
5、实现聊天室私聊。