# 基本认证（已停用）

Source: https://docs.sisk-framework.org/zh-cn/docs/extensions/basic-auth.html

> [!CAUTION]
> **已停用，请勿使用。** Sisk.BasicAuth 包不再维护，并已在 NuGet 上标记为已弃用，且没有替代包。其 `BasicAuthenticateRequestHandler` 不会解码标准 HTTP 客户端发送的 Base64 凭证，导致已认证的请求被拒绝。请使用您自己的[请求处理程序](https://docs.sisk-framework.org/zh-cn/docs/fundamentals/request-handlers.md)实现 Basic 认证，读取 [HttpHeaderCollection.Authorization](https://docs.sisk-framework.org/api/Sisk.Core.Entity.HttpHeaderCollection.Authorization.md) 即可。此页面仅作历史参考保留。

Basic Auth 包添加了一个请求处理程序，能够在您的 Sisk 应用中以极少的配置和工作量处理 Basic 认证方案。Basic HTTP 认证是一种通过用户 ID 和密码对请求进行最小化输入的认证方式，会话完全由客户端控制，且不存在认证或访问令牌。

![基本认证](https://docs.sisk-framework.org/assets/img/basic-auth.svg)

在 [MDN 规范](https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Authentication) 中了解更多关于 Basic 认证方案的信息。

## 安装

要开始使用，请在项目中安装 Sisk.BasicAuth 包：

    > dotnet add package Sisk.BasicAuth

您可以在 [Nuget 仓库](https://www.nuget.org/packages/Sisk.BasicAuth/0.15.0) 中查看更多安装方式。

## 创建您的认证处理程序

您可以为整个模块或单独路由控制认证方案。为此，让我们先编写第一个 Basic 认证处理程序。

在下面的示例中，会连接数据库，检查用户是否存在以及密码是否有效，随后将用户存入上下文包中。

```cs
public class UserAuthHandler : BasicAuthenticateRequestHandler
{
    public UserAuthHandler() : base()
    {
        Realm = "To enter this page, please, inform your credentials.";
    }

    public override HttpResponse? OnValidating(BasicAuthenticationCredentials credentials, HttpContext context)
    {
        DbContext db = new DbContext();

        // 在此情况下，我们使用电子邮件作为用户 ID 字段，
        // 因此将通过电子邮件搜索用户。
        User? user = db.Users.FirstOrDefault(u => u.Email == credentials.UserId);
        if (user == null)
        {
            return base.CreateUnauthorizedResponse("Sorry! No user was found by this email.");
        }

        // 验证凭证密码对该用户是否有效。
        if (!user.ValidatePassword(credentials.Password))
        {
            return base.CreateUnauthorizedResponse("Invalid credentials.");
        }

        // 将已登录的用户添加到 http 上下文
        // 并继续执行
        context.Bag.Add("loggedUser", user);
        return null;
    }
}
```

所以，只需将此请求处理程序关联到我们的路由或类。

```cs
public class UsersController
{
    [RouteGet("/")]
    [RequestHandler(typeof(UserAuthHandler))]
    public string Index(HttpRequest request)
    {
        User loggedUser = request.Bag.Get<User>();
        return $"Hello, {loggedUser.Name}!";
    }
}
```

或使用 [RouterModule](https://docs.sisk-framework.org/api/Sisk.Core.Routing.RouterModule.md) 类：

```cs
public class UsersController : RouterModule
{
    public ClientModule()
    {
        // 此类中的所有路由都将由
        // UserAuthHandler 处理。
        base.HasRequestHandler(new UserAuthHandler());
    }
    
    [RouteGet("/")]
    public string Index(HttpRequest request)
    {
        User loggedUser = request.Bag.Get<User>();
        return $"Hello, {loggedUser.Name}!";
    }
}
```

## 备注

Basic 认证的主要职责在客户端完成。存储、缓存控制和加密均在客户端本地处理。服务器仅接收凭证并验证是否允许访问。

请注意，此方法并非最安全的方案，因为它将大量责任放在客户端，难以追踪并维护凭证的安全性。此外，密码必须在安全连接（SSL）环境下传输，因为它们本身没有加密。请求头的短暂拦截就可能泄露用户的访问凭证。

在生产环境的应用中应选择更强大的认证方案，并避免使用过多现成组件，因为它们可能不适配项目需求，进而导致安全风险。
