tigerwill90/xsrf-middleware

此包已被废弃,不再维护。没有建议的替代包。

基于双重提交模式的 Csrf 保护,cookie - JWT 替代品

1.3.1 2018-02-18 23:18 UTC

This package is not auto-updated.

Last update: 2020-08-22 06:50:07 UTC


README

Latest Stable Version Latest Unstable Version License MIT Build Status codecov

PSR-7 & PSR-15 : CSRF 保护替代 JWT/Branca 认证令牌

基于双重提交模式,cookie - JWT/Branca 替代品进行 Csrf 保护。

它基于 PSR-7 JWT 认证中间件,由 Tuupola 提供。 此中间件旨在与 JWT/Branca 认证方法一起使用,并可用于任何使用 PSR-7 或 PSR-15 风格中间件的框架(自 v1.1.0 版起)。它已在 Slim 框架 上进行了测试

此中间件不提供生成 Branca/JWT 令牌的方法。但是,您可以在下面的链接中找到生成令牌所需的所有内容。

目标是保护 REST API 免受 跨站请求伪造 攻击,使用双重提交模式(无状态)。

它是如何工作的?

有时您想将 Jwt/Branca 令牌保存在一个 http-only cookie 中。由于无法获取它,您的有效负载内容是安全的。这对于 JWT 特别如此,因为它具有未加密的有效负载。但是,这种保护使您的 API 易受 Csrf 攻击。

当用户登录到网站时

  • 生成一个具有伪随机值的反 Csrf 令牌
  • 生成 JWTBranca 并将之前生成的 令牌 设置为有效负载属性之一
  • http-onlysecure cookie 中将 JWTBranca 发送到前端
  • 在响应体中发送之前生成的 令牌

当认证的 API 消费者想要访问您的 API 时,您需要将反 Csrf 令牌附加为

  • 最终一个具有唯一名称的 cookie
  • 头属性
  • 请求体参数

对于所有不安全的操作 [POST | PUT | PATCH | DELETE],中间件将检查 http-only cookie 中的 令牌 和 JWT 或 Branca,以检查它们是否匹配。如果不匹配,则返回 401 状态

依赖项

安装

composer require tigerwill90/xsrf-middleware

用法

配置选项作为数组传递。没有必填参数。

$app = new Slim\App

$app->add(new Tigerwill90\Middleware\XsrfProtection([]));

当请求时,中间件将检查令牌和 cookie 以检查值是否匹配。如果找不到 cookie 或令牌,则服务器将响应 401 未授权

可选参数

路径

可选的 path 参数允许您指定哪些 API 资源受到双重提交模式的保护。它可以是一个字符串或一个数组。您不需要指定每个 URL。

默认参数是 /

$app = new Slim\App

$app->add(new Tigerwill90\Middleware\XsrfProtection([
    "path" => "/api" /* or ["/api", "/admin"]*/
]));

在这个例子中,所有以 /api 开头的资源都将受到保护。

中继

可选的 passthrough 参数允许您指定对 path 参数的例外。它可以是字符串或数组。

默认参数是 null

$app = new Slim\App

$app->add(new Tigerwill90\Middleware\XsrfProtection([
    "path" => ["/api", "/admin"],
    "passthrough" => "/api/orders"
]));

在这个例子中,所有以 /api/admin 开头的资源都将受到保护,除了 /api/orders

防CSRF

可选的 anticsrf 参数允许您指定防CSRF的cookie、header或参数的名称。

默认参数是 xCsrf

$app = new Slim\App

$app->add(new Tigerwill90\Middleware\XsrfProtection([
    "path" => ["/api", "/admin"],
    "anticsrf" => "xCsrf"
]));

在这个例子中,如果存在名为"xCsrf"的cookie、header或请求参数,中间件将比较其值与指定的JWT/Branca令牌claim值。

令牌

根据 PSR-7 JWT身份验证中间件 文档,当令牌成功解码并认证成功时,解码令牌的内容将被保存为$request的属性。可选的 token 参数允许您指定中间件需要在$request中查找的JWT/Branca令牌属性名称。

默认参数是 token

$app = new Slim\App

$app->add(new Tigerwill90\Middleware\XsrfProtection([
"path" => ["/api", "/admin"],
"token" => "jwt"
]));

有效载荷

或者 您也可以在可选的 payload 参数中传递解码令牌的内容。

默认值是 null

$app = new Slim\App

$app->add(new Tigerwill90\Middleware\XsrfProtection([
  "path" => ["/api", "/admin"],
  "payload" => $container["decoded"]
]));

声明

JWT/Branca的美丽之处在于您可以在令牌中传递额外的数据,如角色、权限等。因此,我们可以比较指定的声明与httponly cookie。

[
   "uid" => 1,
   "iat" => "1428819941",
   "exp" => "1744352741",
   "aud" => "www.example.com",
   "roles" => [1,0,1,1,1],
   "xsrf" => "thepseudorandomvaluegeneratedforbothcookieandtoken"
]

可选的 claim 参数允许您指定中间件需要在解码的JWT/Branca令牌中查找的claim名称。

默认值是 csrf

$app = new Slim\App

$app->add(new Tigerwill90\Middleware\XsrfProtection([
  "path" => ["/api", "/admin"],
  "claim" => "xsrf"
]));

根据这个例子,当发送请求到您的API时,您应该在header中有一个名为httponly的cookie和一个authorization token,这两个都设置了值为thepseudorandomvaluegeneratedforbothcookieandtoken

记录器

可选的 logger 参数允许您传递一个PSR-3兼容的记录器来处理调试。

use Monolog\Logger;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Formatter\LineFormatter;

$app = new Slim\App

$logger = new Logger("slim");
$formatter = new LineFormatter(
    "[%datetime%] [%level_name%]: %message% %context%\n",
    null,
    true,
    true
);

$rotating = new RotatingFileHandler(__DIR__ . "/logs/xsrf.log", 0, Logger::DEBUG);
$rotating->setFormatter($formatter);
$logger->pushHandler($rotating);

$app->add(new Tigerwill90\Middleware\XsrfProtection([
  "path" => ["/api", "/admin"],
  "claim" => "xsrf",
  "logger" => $logger
]));

在这个例子中,我们将一个Logger $logger实例传递给中间件。

[2017-12-06 01:14:05] [WARNING]: Payload not found in parameter 
[2017-12-06 01:14:05] [DEBUG]: Token and cookie don't match, access denied ! 

错误

当访问被拒绝时,会调用错误。它接受最后一个错误消息作为参数。

$app = new Slim\App

$app->add(new Tigerwill90\Middleware\XsrfProtection([
  "path" => ["/api", "/admin"],
  "claim" => "xsrf",
  "error" => function ($response, $arguments) {
       $data["message"] = $arguments["message];
       return $response
                ->withHeader("Content-Type", "application/json")
                ->write(json_encode($data));
  }
]));

MessagePack

可选的 msgpack 参数允许您使用 MessagePack 序列化格式。

默认值是 false

$app = new Slim\App
 
$app->add(new Tigerwill90\Middleware\XsrfProtection([
   "path" => ["/api", "/admin"],
   "payload" => $container["decoded"]
   "msgpack" => true
]));

使用JWT/Branca身份验证中间件的实现

Branca/JWT身份验证中间件需要在Xsrf中间件保护之前运行。

$container = $app->getContainer();

$container["XsrfProtection"] = function($c) {
    function new \Tigerwill90\Middleware\XsrfProtection([
        "path" => "/api",
        "passthrough" => ["/api/users/signin", "/api/users/token"],
        "anticsrf" => "xCsrf",
        "token" => "jwt",
        "claim" => "xsrf"
    ]);
};

 $container["JwtAuthentication"] = function($c) {
    return new \Slim\Middleware\JwtAuthentication([
        "secure" => true,
        "path" => "/api",
        "passthrough" => ["/api/users/signin", "/api/users/token"],
        "attribute" => "jwt",
        "secret" => getenv("JWT_SECRET")
    ]);
 };
 
 $app->add("XsrfProtection");
 $app->add("JwtAuthentication");

测试

phpunit

许可

MIT许可证(MIT)。请参阅许可证文件获取更多信息。