使用 React hooks、.NET Core Web API 和 SQL Server 实现身份验证和授权

IT技术 reactjs authentication .net-core jwt asp.net-identity
2021-05-24 22:11:04

我有一个使用 React 挂钩、SQL Server 数据库和 .NET Core 3.1 Web API 构建的应用程序。我真的很难理解所有活动部件的关系。我想避免重新发明轮子并利用现有的库和框架。JWT 似乎是从我学到的东西到这里的方式,它只是有点令人困惑。以下是我的要求:

  1. 创建帐户并使用自定义站点帐户登录/注销或使用 Google/Facebook/Microsoft/等。(我可以从一个或另一个开始,但不想把自己装进去并重写大量的东西来添加另一个)
  2. 利用现有项目中的 .NET Core Identity 来处理 SQL Server 数据库中的用户、角色等。
  3. 使用 React 钩子模式(如果必须的话,我可以通过翻译类组件跛行我的方式)

我想我在所有的解耦中迷失了(这通常是一件好事!)我看到关于 React 的文章和虚拟后端,我迷路了。我看到有关 .NET Core 的帖子,但不知道如何将它与 React 一起使用。从概念上讲,其中大部分是有道理的,但我还没有找到可以帮助我理解代码从头到尾应该是什么样子的地方。

所以这里是我的问题!

  1. React 前端应用程序和 React auth 服务是一回事吗?他们可以吗?他们必须是吗?
  2. JWT 字符串是在 React 端还是.NET 端生成的?最好的图书馆?
  3. MS Identity Server 如何(或是否?)适合这个等式?
  4. 尽管看了大约 100 篇文章,但我并不完全理解刷新令牌的概念。是否 100% 需要刷新令牌?使用/不使用它们的好处/缺点?

需要整理的东西很多,我只是希望有人可以帮助我简化。

2个回答
  1. React 应用程序中处理身份验证的部分自然应该是一个组件,然后由应用程序的其他部分(例如,通过登录组件)导入。您可以在此处查看示例教程

  2. JWT 是在服务器端生成的,在您的情况下是 .NET Core。它必须在服务器端创建,因为在客户端生成它意味着在那里拥有秘密,这样攻击者就可以窃取它并创建有效的令牌。另请参阅此答案
    至于生成:你可以自己生成,也可以直接使用认证框架(如IdentityServer4)或第三方认证(如使用谷歌登录)为你生成。如果你决定自己生成它,我认为你不需要复杂的东西(我的意思是,你甚至不需要像JWT.NET这样的库)。只需使用一个简单的教程,就像这个

  3. IdentityServer4 是一个身份验证框架,它实现了 OpenID Connect 和 OAuth 2.0 协议,默认使用 JWT 身份验证。
    使用它可以获得身份验证行为,包括例如登录和注销(它实际上带有自己的登录页面 ( Login.cshtml, Logout.cshtml)),但不包括注册。
    建议仅将其用于该目的,您可以建议以下两个答案以更好地理解处理身份验证时的关注点分离(尽管问题的标题指的是用户创建,但答案也专门针对身份验证):

  4. 如果您想为您的应用程序添加更多安全性,您将exp在 JWT 中拥有一个声明。如果您有一个exp声明并且不希望清晰的用户在每次 JWT 过期时都必须重新登录,您将拥有刷新令牌。您使用刷新令牌来获取全新的访问令牌。如果您将使用 IdentityServer4,则已经为您实现了刷新令牌,但您必须明确配置它们。建议以下来源:

    另外,我不知道您阅读的那 100 篇文章是什么:) 但我认为以下 SO 帖子很棒:

这个问题太笼统了,无法添加简单的答案。回答您的编号问题很可能不会帮助您推进您的项目。因此,我试图在这里提供一个通用的答案。

帐户创建

由于您有一个带有数据库的后端,因此必须在服务器上创建帐户。因此,您在 React 应用程序中捕获用户名和密码,然后将此数据发送到后端的注册端点。请注意,出于安全原因,您可能希望在发送之前对密码进行哈希处理,并且很可能无论如何它都会以这种方式存储在数据库中。您的后端此时可以使用提交的数据进行验证(例如验证已使用的用户名等)。如果详细信息有效,则将详细信息存储在数据库中。如果需要,您还可以在这一点上与 MS IS 联系起来。存储帐户详细信息后,您可以使用 JWT 或任何其他库生成令牌。此令牌保存在服务器上并在初始注册请求的响应中返回。也可以选择在此处返回刷新令牌。

令牌处理

如果注册成功,注册请求应返回如上所述的身份验证令牌。这个身份验证令牌(和可选的刷新令牌)应该存储在客户端(例如react上下文,或者如果你正在使用一些像 redux 这样的状态管理库,那么你可以将它设置在全局状态中)。

如果您想使用“记住我”,那么存储的令牌应该保留在客户端。

在此阶段,您的用户已登录。从现在开始,您将在所有请求的标头中将此令牌发送到您的后端。然后您的后端可以使用存储在您的数据库中的令牌查找收到的令牌,并决定是否允许当前请求。

令牌刷新

出于安全原因,您可能希望为所有发布的令牌设置 TTL。即在一定时间后使令牌无效。当使用过期令牌的请求进入您的后端时,您会返回一个过期的响应,该响应应该在客户端处理。客户端应使用本地存储的刷新令牌进行刷新令牌调用。这应该在服务器上生成一个新的身份验证令牌,并用新生成的令牌替换旧令牌。

您可以将 TTL 设置为“永远保持”,在这种情况下您将不需要处理令牌刷新。

登录

您的 React 应用程序会捕获用户/密码,并以与注册相同的方式将其发送到您的后端。后端验证帐户详细信息并生成并返回新令牌。然后,您的客户应以与上述注册时相同的方式使用此令牌。

还有数以百万计的其他细节可以在这里解决,但可能足以让您开始。