slim-jwt-auth, PSR 7和 PSR 15 JWT认证中间件

分享于 

15分钟阅读

GitHub

  繁體 雙語
JSON Web Token Authentication for Slim Framework
  • 源代码名称:slim-jwt-auth
  • 源代码网址:http://www.github.com/tuupola/slim-jwt-auth
  • slim-jwt-auth源代码文档
  • slim-jwt-auth源代码下载
  • Git URL:
    git://www.github.com/tuupola/slim-jwt-auth.git
    Git Clone代码到本地:
    git clone http://www.github.com/tuupola/slim-jwt-auth
    Subversion代码到本地:
    $ svn co --depth empty http://www.github.com/tuupola/slim-jwt-auth
    Checked out revision 1.
    $ cd repo
    $ svn up trunk
    
    PSR-7 JWT认证中间件

    这个中间件实现了JSON网络令牌认证。 它最初是为瘦开发的,但是可以使用 PSR-7 风格中间件的任何框架。 它已经用瘦框架Zend Expressive测试进行了测试。

    Latest VersionPackagistSoftware LicenseBuild StatusCoverage

    注意你正在阅读 2.x 分支文件的文档。 ! 如果你正在寻找 PSR-15 支持,请参阅 3.x 分支。 这两个分支不向后兼容,请参见升级插件,了解如何升级。

    中间件不实现OAuth授权服务器,也不提供生成。发布或者存储身份验证令牌的方式。 它仅在通过 header 或者cookie传递时解析和验证令牌。 当你想使用 JSON网络标记作为API密钥时,这很有用。

    例如实现见瘦API框架。

    安装

    使用 Composer 安装最新版本。

    $ composer require tuupola/slim-jwt-auth

    如果使用Apache将以下内容添加到 .htaccess 文件。 否则PHP就不能访问 Authorization: Bearer header。

    RewriteRule. * - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    用法

    配置选项作为 array 传递。 唯一的强制参数是 secret,它用于验证令牌签名。 请注意,secret 不是令牌。 这是你用来签署令牌的秘密。

    为了简单起见,在代码中显示 secret 硬编码。 在现实生活中,你应该把它。 好的选项是环境变量。 你可以使用 dotenv插件或者类似的开发。 假设你使用的是瘦框架。

    $app=newSlimApp();$app->add(newSlimMiddlewareJwtAuthentication(["secret"=>"supersecretkeyyoushouldnotcommittogithub"]));

    你的密钥被存储为环境变量的示例:

    $app=newSlimApp();$app->add(newSlimMiddlewareJwtAuthentication(["secret"=>getenv("JWT_SECRET")]));

    当发出请求时,中间件试图验证和解码令牌。 如果未找到令牌或者在验证和解码时出现错误,服务器将响应 401 Unauthorized

    当令牌被篡改或者令牌已过期时,会触发验证错误。 有关所有可能的验证错误,请参见 JWT库源。

    可选参数

    路径

    可选 path 参数允许你指定网站的protected 部分。 它可以是一个字符串,也可以是一个 array。 你不需要指定每个 URL。 相反,把 path 设置当作一个文件夹。 在下面的示例中,所有以 /api 开头的。

    $app=newSlimApp();$app->add(newSlimMiddlewareJwtAuthentication(["path"=>"/api", /* or ["/api","/admin"] */"secret"=>"supersecretkeyyoushouldnotcommittogithub"]));

    通道

    使用可选的passthrough 参数,你可以对 path 参数。 在下面的例子中,以 /api/admin 开头的例子将被验证,并且不会被验证的/api/token/admin/ping

    $app=newSlimApp();$app->add(newSlimMiddlewareJwtAuthentication(["path"=> ["/api", "/admin"],"passthrough"=> ["/api/token", "/admin/ping"],"secret"=>"supersecretkeyyoushouldnotcommittogithub"]));

    环境

    默认情况下,中间件试图从 HTTP_AUTHORIZATIONREDIRECT_HTTP_AUTHORIZATION 环境中找到令牌。 你可以使用 environment 参数进行更改。 注意,通常也应该使用匹配的header 参数。

    $app=newSlimApp();$app->add(newSlimMiddlewareJwtAuthentication(["environment"=> ["HTTP_BRAWNDO", "REDIRECT_HTTP_BRAWNDO"],"header"=>"Brawndo","secret"=>"supersecretkeyyoushouldnotcommittogithub"]));

    如果没有从环境中找到令牌,中间件会尝试从 Authorization header 找到它。 你可以使用 header 参数更改 cookie NAME。 注意,通常也应该使用匹配的environment 参数。

    $app=newSlimApp();$app->add(newSlimMiddlewareJwtAuthentication(["environment"=>"HTTP_X_TOKEN","header"=>"X-Token","secret"=>"supersecretkeyyoushouldnotcommittogithub"]));

    Cookie

    如果没有从环境或者 header 找到令牌,那么中间件将尝试从名为 token的cookie中找到它。 你可以使用 cookie 参数更改 cookie NAME。

    $app=newSlimApp();$app->add(newSlimMiddlewareJwtAuthentication(["cookie"=>"nekot","secret"=>"supersecretkeyyoushouldnotcommittogithub"]));

    正则表达式

    默认情况下,中间件假定 header的值为 Bearer <token> 格式。 你可以使用 regexp 参数更改这里行为。 例如如果你有自定义 header ( 如 X-Token: <token> ),则应该同时传递 header 和regexp参数。

    $app=newSlimApp();$app->add(newSlimMiddlewareJwtAuthentication(["header"=>"X-Token","regexp"=>"/(.*)/","secret"=>"supersecretkeyyoushouldnotcommittogithub"]));

    算法

    你可以通过 algorithm 参数设置支持的算法。 可以是字符串的字符串,也可以是字符串的array。 默认值为 ["HS256","HS512","HS384"]。支持的算法为 HS256HS384HS512RS256。 注意,启用 HS256RS256 都是一个安全风险。

    $app=newSlimApp();$app->add(newSlimMiddlewareJwtAuthentication(["secret"=>"supersecretkeyyoushouldnotcommittogithub","algorithm"=> ["HS256", "HS384"]]));

    属性

    成功解码令牌并将解码后的令牌内容作为属性保存为 $request 对象的内容时,。 你可以通过以下方式更改。 attribute 参数设置为 null 或者 false 以禁用这里 behavour

    $app=newSlimApp();$app->add(newSlimMiddlewareJwtAuthentication(["attribute"=>"jwt","secret"=>"supersecretkeyyoushouldnotcommittogithub"]));/*.. . */$decoded=$request->getAttribute("jwt");

    记录器

    可选 logger 参数允许你传入 PSR-3 兼容记录器以帮助调试或者它的他应用程序日志记录需求。

    useMonologLogger;useMonologHandlerRotatingFileHandler;$app=newSlimApp();$logger=newLogger("slim");$rotating=newRotatingFileHandler(__DIR__."/logs/slim.log", 0, Logger::DEBUG);$logger->pushHandler($rotating);$app->add(newSlimMiddlewareJwtAuthentication(["path"=>"/api","logger"=>$logger,"secret"=>"supersecretkeyyoushouldnotcommittogithub"]));

    回调

    只有在身份验证成功时才调用回调。 它在参数中接收解码的标记。 如果回调返回布尔 false 身份验证,则强制失败。

    还可以使用回调来存储已经解码标记的值以便以后使用。

    $app=newSlimApp();$container=$app->getContainer();$container["jwt"] =function ($container) {returnnewStdClass;};$app->add(newSlimMiddlewareJwtAuthentication(["secret"=>"supersecretkeyyoushouldnotcommittogithub","callback"=>function ($request, $response, $arguments) use ($container) {$container["jwt"] =$arguments["decoded"]; }]));

    错误

    身份验证失败时调用错误。 它在参数中接收最后一个错误消息。

    $app=newSlimApp();$app->add(newSlimMiddlewareJwtAuthentication(["secret"=>"supersecretkeyyoushouldnotcommittogithub","error"=>function ($request, $response, $arguments) {$data["status"] ="error";$data["message"] =$arguments["message"];return$response->withHeader("Content-Type", "application/json")->write(json_encode($data, JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT)); }]));

    规则

    可选的rules 参数允许你传递规则,这些规则定义是否应该对请求进行身份验证或者。 规则是可以调用的,它将请求作为参数接收。 如果任何规则返回布尔 false,请求将不会被验证。

    默认情况下,中间件配置如下。 所有路径都通过除 OPTIONS 之外的所有请求方法进行身份验证。

    $app=newSlimApp();$app->add(newSlimMiddlewareJwtAuthentication(["rules"=> [newSlimMiddlewareJwtAuthenticationRequestPathRule(["path"=>"/","passthrough"=> [] ]),newSlimMiddlewareJwtAuthenticationRequestMethodRule(["passthrough"=> ["OPTIONS"] ]) ]]));

    RequestPathRule既包含 path 参数,也包含 passthrough 参数。 后包含不应该被验证的路径。 RequestMethodRule包含请求方法的passthrough 参数,也不应该对它的进行身份验证。 把 passthrough 当作白名单。

    这个例子的例子是 API。 令牌可以通过 HTTP基本认证 protected 地址获取。 还有一个不受保护的url用于 ping。 API的其余部分是JWT中间件的protected。

    $app=newSlimApp();$app->add(newSlimMiddlewareJwtAuthentication(["logger"=>$logger,"secret"=>"supersecretkeyyoushouldnotcommittogithub","rules"=> [newRequestPathRule(["path"=>"/api","passthrough"=> ["/api/token", "/api/ping"] ]),newSlimMiddlewareJwtAuthenticationRequestMethodRule(["passthrough"=> ["OPTIONS"] ]) ]]));$app->add(newSlimMiddlewareHttpBasicAuthentication(["path"=>"/api/token","users"=> ["user"=>"password" ]]));$app->post("/token", function () {/* Here generate and return JWT to the client. */});

    安全性

    JSON网络令牌实际上是密码。 你应该将它们视为这样,你应该始终使用 HTTPS。 如果中间件检测到不安全的使用,它将抛出一个 RuntimeException。 这里规则对于本地主机上的请求是宽松的。 要允许不安全的使用,必须通过将 secure 设置为 false 来手动启用。

    $app->add(newSlimMiddlewareJwtAuthentication(["secure"=>false,"secret"=>"supersecretkeyyoushouldnotcommittogithub"]));

    或者,你可以列出你的开发主机以获得宽松的安全性。

    $app->add(newSlimMiddlewareJwtAuthentication(["secure"=>true,"relaxed"=> ["localhost", "dev.example.com"],"secret"=>"supersecretkeyyoushouldnotcommittogithub"]));

    授权

    默认情况下,中间件仅验证。 这并不是很有趣。 美丽的JWT是你可以在标记中传递额外的数据。 这里数据可以包括可以用于授权的作用域。

    实现令牌数据存储方式或者可能的授权实现是你需要付出的代价。

    假设你拥有包含范围数据的标记。 在中间件回调中,将解码的令牌数据存储到 $app->jwt 中,然后将它的用于授权。

    ["iat"=>"1428819941","exp"=>"1744352741","scope"=> ["read", "write", "delete"]]
    $app=newSlimApp();$container=$app->getContainer();$container["jwt"] =function ($container) {returnnewStdClass;};$app->add(newSlimMiddlewareJwtAuthentication(["secret"=>"supersecretkeyyoushouldnotcommittogithub","callback"=>function ($request, $response, $arguments) use ($container) {$container["jwt"] =$arguments["decoded"]; }]));$app->delete("/item/{id}", function ($request, $response, $arguments) {if (in_array("delete", $this->jwt->scope)) {/* Code for deleting item */ } else {/* No scope so respond with 401 Unauthorized */return$response->withStatus(401); }});

    测试

    你可以手动运行单个测试。

    $ composer phplint
    $ composer phpcs
    $ composer phpunit

    。或者自动更改每个代码。 你需要 才能工作。

    $ composer watch

    请参见为细节提供帮助。

    安全性

    如果发现任何相关的安全问题,请电子邮件 tuupola@appelsiini.net,而不是使用问题跟踪程序。

    许可证

    MIT许可证( MIT ) 有关详细信息,请参阅许可证文件


    auth  中间件  JWT  psr-7  psr-1  
    相关文章