一、简介
前后端分离的站点一般都会用jwt或IdentityServer4之类的生成token的方式进行登录鉴权。这里要说的是小项目没有做前后端分离的时站点登录授权的正确方式。
二、传统的授权方式
这里说一下传统授权方式,传统授权方式用session或cookies来完成。
- 在请求某个Action之前去做校验,验证当前操作者是否登录过,登录过就有权限
- 如果没有权限就跳转到登录页中去
- 传统登录授权用的AOP-Filter:ActionFilter。
前后端分离的站点一般都会用jwt或IdentityServer4之类的生成token的方式进行登录鉴权。这里要说的是小项目没有做前后端分离的时站点登录授权的正确方式。
这里说一下传统授权方式,传统授权方式用session或cookies来完成。
比如下面的Razor视图代码:
@{ ViewBag.Title = "代码改变世界"; } <title>@ViewBag.Title</title>
输出的html代码变成了:
<title>代码改变世界</title>
我们能否以更少的资源消耗,获得 Electron 的利用 web 技术构建的桌面应用程序的优势?
Electron 在 2014 首次开源,作为一种使用 Web 技术(HTML+CSS+JS)构建桌面应用程序的方式,它迅速流行起来。其设计的核心思想是将可预测的环境捆绑在一起:
它捆绑了自己的 Chromium 副本, 因此,你可以确定你的 HTML/CSS 将如何被渲染,不必担心 IE 浏览器(等) 随机的旧版本。
它捆绑了自己的 Node.js 副本, 因此,你拥有已知的一个可移植编程平台的版本,它超越了浏览器沙箱,可以直接与本机系统交互。
这些选择在五年前很有价值,但到了 2019 年底,你可能会做出不同的选择。这些选择也是为什么 Electron 对资源极度渴求却也会闻名的关键。默认的空白 Electron 8.0.0 应用程序需要下载 164MB(压缩后 66MB),并作为 4 个单独的进程运行,总共消耗 150MB。
这些数字在您看来完全可以满足您的场景。如果是这样,那太好了!这篇文章并不是要抨击 Electron,它是一个运行良好的项目,人们显然已经成功地使用了它。在这篇文章中,我只是想思考一下我们还有什么其他的选择。
IdentityServer4(以下简称 Id4) 是 Asp.Net Core 中一个非常流行的 OpenId Connect 和 OAuth 2.0 框架,可以轻松集成到 Asp.Net Core 应用中,并且与 Asp.Net Core Identity 也可以轻松集成。博客园也有大佬发布了很多关于 Id4 的相关文章。比如晓晨Master的系列入门教程:IdentityServer4 中文文档与实战,我也是看他的教程学习入门的,教程基于 .Net Core 2.x,但是影响不大。
相对于ASP.NET MVC以及ASP.NET Core MVC中的旧版本路由特性, 在ASP.NET Core 3.0中新增了一个不错的扩展点,即程序获取到路由后,可以将其动态指向一个给定的controller/action.
这个功能有非常多的使用场景。如果你正在使用从ASP.NET Core 3.0 Preview 7及更高版本,你就可以在ASP.NET Core 3.0中使用它了。
PS: 官方没有在Release Notes中提到这一点。
下面就让我们一起来看一看ASP.NET Core 3.0中的动态路由。
到目前为止,我们定义的ServiceProvider已经实现了基本的服务提供和回收功能,但是依然漏掉了一些必需的细节特性。这些特性包括如何针对IServiceProvider接口提供一个ServiceProvider对象,何创建ServiceScope,以及如何提供一个服务实例的集合。
通过上一篇的介绍我们应该对实现在ServiceProvider的总体设计有了一个大致的了解,但是我们刻意回避一个重要的话题,即服务实例最终究竟是采用何种方式提供出来的。ServiceProvider最终采用何种方式提供我们所需的服务实例取决于最终选择了怎样的ServiceCallSite,而服务注册是采用的ServiceDescriptor有决定了ServiceCallSite类型的选择。我们将众多不同类型的ServiceCallSite大体分成两组,一组用来创建最终的服务实例,另一类则与生命周期的管理有关。
本系列前面的文章我们主要以编程的角度对ASP.NET Core的依赖注入系统进行了详细的介绍,如果读者朋友们对这些内容具有深刻的理解,我相信你们已经可以正确是使用这些与依赖注入相关的API了。如果你还对这个依赖注入系统底层的实现原理具有好奇心,可以继续阅读这一节的内容。
ServiceProvider最终提供的服务实例都是根据对应的ServiceDescriptor创建的,对于一个具体的ServiceDescriptor对象来说,如果它的ImplementationInstance和ImplementationFactory属性均为Null,那么ServiceProvider最终会利用其ImplementationType属性返回的真实类型选择一个适合的构造函数来创建最终的服务实例。我们知道服务服务的真实类型可以定义了多个构造函数,那么ServiceProvider针对构造函数的选择会采用怎样的策略呢?
在采用了依赖注入的应用中,我们总是直接利用DI容器直接获取所需的服务实例,换句话说,DI容器起到了一个服务提供者的角色,它能够根据我们提供的服务描述信息提供一个可用的服务对象。ASP.NET Core中的DI容器体现为一个实现了IServiceProvider接口的对象。