tuupola / slim-basic-auth
PSR-7 和 PSR-15 HTTP 基本认证中间件
Requires
- php: ^7.1|^8.0
- psr/http-message: ^1.0.1
- psr/http-server-middleware: ^1.0
- tuupola/callable-handler: ^0.3.0|^0.4.0|^1.0
- tuupola/http-factory: ^0.4.0|^1.0.2
Requires (Dev)
- equip/dispatch: ^2.0
- overtrue/phplint: ^2.0.2
- phpstan/phpstan: ^0.12.43
- phpunit/phpunit: ^7.0|^8.0|^9.0
- squizlabs/php_codesniffer: ^3.3.2
- symfony/process: ^3.3
- zendframework/zend-diactoros: ^1.3|^2.0
- 4.x-dev
- 3.x-dev
- 3.3.1
- 3.3.0
- 3.2.1
- 3.2.0
- 3.1.0
- 3.0.0
- 3.0.0-rc.5
- 3.0.0-rc.4
- 3.0.0-rc.3
- 3.0.0-rc.2
- 3.0.0-rc.1
- 2.x-dev
- 2.3.0
- 2.2.2
- 2.2.1
- 2.2.0
- 2.1.1
- 2.1.0
- 2.0.4
- 2.0.3
- 2.0.2
- 2.0.1
- 2.0.0
- 1.x-dev
- 1.0.2
- 1.0.1
- 1.0.0
- 0.12.1
- 0.12.0
- 0.11.0
- 0.10.0
- 0.9.0
- 0.8.2
- 0.8.1
- 0.8.0
- 0.7.1
- 0.7.0
- 0.6.0
- 0.5.0
- dev-phpcs-ecs
- dev-php74-travis
- dev-gimme-gimme
This package is auto-updated.
Last update: 2024-09-11 12:26:25 UTC
README
此中间件实现了 HTTP 基本认证。它最初是为 Slim 开发的,但可以与所有使用 PSR-7 或 PSR-15 风格中间件的框架一起使用。它已在 Slim 框架 和 Zend Expressive 上进行测试。
请注意!您正在阅读 3.x 分支的文档 3.x branch,它仅适用于 PHP 7.1 及以上版本。如果您正在使用较旧版本的 PHP,请参阅 2.x 分支。这两个分支不兼容,有关升级说明,请参阅 UPGRADING。
安装
使用 composer 安装最新版本。
$ composer require tuupola/slim-basic-auth
使用方法
配置选项作为数组传递。必需参数是 users
。这是一个数组,您可以在其中传递一个或多个 "username" => "password"
组合。用户名是键,密码是值。
$app = new Slim\App; $app->add(new Tuupola\Middleware\HttpBasicAuthentication([ "users" => [ "root" => "t00r", "somebody" => "passw0rd" ] ]));
与 Zend Expressive 相同。
$app = Zend\Expressive\AppFactory::create(); $app->pipe(new Tuupola\Middleware\HttpBasicAuthentication([ "users" => [ "root" => "t00r", "user" => "passw0rd" ] ]));
以下示例假设您正在使用 Slim 框架。
明文密码仅适用于快速测试。您可能想使用散列密码。可以使用 htpasswd
命令行工具或 password_hash() PHP 函数生成散列密码。
$ htpasswd -nbBC 10 root t00r
root:$2y$10$1lwCIlqktFZwEBIppL4ak.I1AHxjoKy9stLnbedwVMrt92aGz82.O
$ htpasswd -nbBC 10 somebody passw0rd
somebody:$2y$10$6/vGXuMUoRlJUeDN.bUWduge4GhQbgPkm6pfyGxwgEWT0vEkHKBUW
$app = new Slim\App; $app->add(new Tuupola\Middleware\HttpBasicAuthentication([ "users" => [ "root" => '$2y$10$1lwCIlqktFZwEBIppL4ak.I1AHxjoKy9stLnbedwVMrt92aGz82.O', "somebody" => '$2y$10$6/vGXuMUoRlJUeDN.bUWduge4GhQbgPkm6pfyGxwgEWT0vEkHKBUW' ] ]));
即使您使用散列密码,将凭据存储在代码中也不是一个好主意。相反,您可以将它们存储在环境变量中或外部文件中,这些文件不会提交到 GitHub。
$app = new Slim\App; $app->add(new Tuupola\Middleware\HttpBasicAuthentication([ "users" => [ "admin" => getenv("ADMIN_PASSWORD") ] ]));
可选参数
路径
可选的 path
参数允许您指定网站的受保护部分。它可以是字符串或数组。您不需要指定每个 URL。相反,将 path
设置视为文件夹。在下面的示例中,所有以 /api
开头的 URL 都将进行认证。
$app = new Slim\App; $app->add(new Tuupola\Middleware\HttpBasicAuthentication([ "path" => "/api", /* or ["/admin", "/api"] */ "realm" => "Protected", "users" => [ "root" => "t00r", "somebody" => "passw0rd" ] ]));
忽略
使用可选的 ignore
参数,您可以针对 path
参数进行例外处理。在下面的示例中,所有以 /api
和 /admin
开头的 URL 都将进行认证,但 /api/token
和 /admin/ping
除外,它们将不进行认证。
$app = new Slim\App; $app->add(new Tuupola\Middleware\HttpBasicAuthentication([ "path" => ["/api", "/admin"], "ignore" => ["/api/token", "/admin/ping"], "realm" => "Protected", "users" => [ "root" => "t00r", "somebody" => "passw0rd" ] ]));
之前
只有当认证成功时才会调用 before
函数,但在调用下一个传入的中间件之前。您可以使用此功能在将请求传递给堆栈中的下一个传入中间件之前更改请求。如果返回值不是 \Psr\Http\Message\RequestInterface
,则返回值将被忽略。
$app = new Slim\App; $app->add(new Tuupola\Middleware\HttpBasicAuthentication([ "path" => "/admin", "realm" => "Protected", "users" => [ "root" => "t00r", "somebody" => "passw0rd" ], "before" => function ($request, $arguments) { return $request->withAttribute("user", $arguments["user"]); } ]));
之后
只有当认证成功并且已经调用传入的中间件堆栈之后,才会调用 after
函数。您可以使用此功能在将响应传递给堆栈中的下一个传出中间件之前更改响应。如果返回值不是 \Psr\Http\Message\ResponseInterface
,则返回值将被忽略。
$app = new Slim\App; $app->add(new Tuupola\Middleware\HttpBasicAuthentication([ "path" => "/admin", "realm" => "Protected", "users" => [ "root" => "t00r", "somebody" => "passw0rd" ], "after" => function ($response, $arguments) { return $response->withHeader("X-Brawndo", "plants crave"); } ]));
安全
基本认证以明文形式传输凭据。因此,始终应与基本认证一起使用 HTTPS。如果中间件检测到通过 HTTP 的不安全使用,它将抛出带有以下消息的 RuntimeException
: Insecure use of middleware over HTTP denied by configuration
。
默认情况下,localhost 可以使用 HTTP。也可以配置 HttpBasicAuthentication
的安全行为,允许
如何配置白名单
您可以列出允许不安全访问的主机。例如,要允许开发主机 dev.example.com
的 HTTP 流量,请将主机名添加到 relaxed
配置密钥。
$app = new Slim\App; $app->add(new Tuupola\Middleware\HttpBasicAuthentication([ "path" => "/admin", "secure" => true, "relaxed" => ["localhost", "dev.example.com"], "users" => [ "root" => "t00r", "somebody" => "passw0rd" ] ]));
允许 HTTPS 终止和转发
如果公共流量在负载均衡器或代理上终止 SSL 并不安全地转发到应用程序主机,HttpBasicAuthentication
可以检查请求头以确保原始客户端请求是安全发起的。要启用,请将字符串 headers
添加到 relaxed
配置密钥。
$app = new Slim\App; $app->add(new Tuupola\Middleware\HttpBasicAuthentication([ "path" => "/admin", "secure" => true, "relaxed" => ["localhost", "headers"], "users" => [ "root" => "t00r", "somebody" => "passw0rd" ] ]));
允许所有未加密流量
要允许任何主机不安全使用,您必须手动将其设置为 false
。这通常不是一个好主意。只有在您知道自己在做什么的情况下才使用。
$app = new Slim\App; $app->add(new Tuupola\Middleware\HttpBasicAuthentication([ "path" => "/admin", "secure" => false, "users" => [ "root" => "t00r", "somebody" => "passw0rd" ] ]));
自定义认证方法
有时仅通过数组传递用户还不够。要针对自定义数据源进行认证,您可以将可调用的对象作为 authenticator
参数传递。这可以是实现 AuthenticatorInterface 的类或匿名函数。可调用的对象接收一个包含 user
和 password
的数组作为参数。在两种情况下,认证器都必须返回 true
或 false
。
如果您正在创建一个随机允许人们登录的企业™ 软件,您可以使用以下方法。
use Tuupola\Middleware\HttpBasicAuthentication\AuthenticatorInterface; use Tuupola\Middleware\HttpBasicAuthentication; class RandomAuthenticator implements AuthenticatorInterface { public function __invoke(array $arguments): bool { return (bool)rand(0,1); } } $app = new Slim\App; $app->add(new HttpBasicAuthentication([ "path" => "/admin", "realm" => "Protected", "authenticator" => new RandomAuthenticator ]));
同样,匿名函数也可以实现相同的功能。
$app = new Slim\App; $app->add(new Tuupola\Middleware\HttpBasicAuthentication([ "path" => "/admin", "realm" => "Protected", "authenticator" => function ($arguments) { return (bool)rand(0,1); } ]));
设置认证失败时的响应体
默认情况下,插件返回一个空的响应体和 401 响应。您可以通过提供错误处理器来返回自定义体。例如,当您需要附加信息来解释为什么认证失败时,这很有用。
$app = new Slim\App; $app->add(new Tuupola\Middleware\HttpBasicAuthentication([ "path" => "/api", "realm" => "Protected", "users" => [ "root" => "t00r", "somebody" => "passw0rd" ], "error" => function ($response, $arguments) { $data = []; $data["status"] = "error"; $data["message"] = $arguments["message"]; $body = $response->getBody(); $body->write(json_encode($data, JSON_UNESCAPED_SLASHES)); return $response->withBody($body); } ]));
与 PDO 的使用
对于那些急于求成的人来说,有一个现成的 PDO 认证器。它涵盖了大多数用例。您可能最终还是要自己实现。
use Tuupola\Middleware\HttpBasicAuthentication\PdoAuthenticator; $pdo = new PDO("sqlite:/tmp/users.sqlite"); $app = new Slim\App; $app->add(new Tuupola\Middleware\HttpBasicAuthentication([ "path" => "/admin", "realm" => "Protected", "authenticator" => new PdoAuthenticator([ "pdo" => $pdo ]) ]));
为了更好的解释,请参阅 Basic Authentication from Database 博客文章。
与 FastCGI 的使用
默认情况下,Apache 不将凭据传递给 FastCGI 进程。如果您使用 mod_fcgi,您可以使用以下方式配置授权头:
FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -host 127.0.0.1:9000 -pass-header Authorization
测试
您可以通过手动或自动在每次代码更改时运行测试来运行测试。自动测试需要 entr 运行。
$ make test
$ brew install entr $ make watch
贡献
有关详细信息,请参阅 CONTRIBUTING。
安全
如果您发现任何与安全相关的问题,请通过电子邮件 [email protected] 联系,而不是使用问题跟踪器。
许可
MIT 许可证 (MIT)。有关更多信息,请参阅 LICENSE。