taproot/认证

该软件包已被废弃且不再维护。作者建议使用 taproot/indieauth 软件包。

将 indieauth 登录(客户端应用)和令牌生成(服务器端应用)添加到您的 Silex/Symfony 应用程序变得非常简单。

v0.2.0 2021-04-21 21:47 UTC

This package is auto-updated.

Last update: 2021-06-24 17:22:31 UTC


README

taproot/authentication 已过时且不再维护。未来的开发将在更新、更兼容和经过更好测试的新 taproot/indieauth 上进行。

taproot/认证

一个库,可以快速将完整的 indieauth/web 登录支持添加到 Silex/Symfony 应用程序中。基于 indieweb/indieauth-client 构建。

安装

使用 Composer 安装

./composer.phar require taproot/authentication:~0.1

用法

taproot/认证暴露了两个函数,给定您的 Silex $app,设置预/后请求处理器并返回一个您可以在任何位置挂载的路由集合。

这两个函数在 $app 上需要几个服务

  • url_generator:一个 Symfony Routing UrlGeneratorInterface 实例,例如 Silex 中由 UrlGeneratorServiceProvider 提供的实例。
  • encryption:一个实现两个方法的对象,string encrypt(mixed $data)mixed decrypt(string $token),能够加密和解密任意数据。通常是一个 [Illuminate\Encryption\Encrypter](https://github.com/illuminate/encryption) 的实例。

这两个函数将可选地使用以下服务,但不是必需的

  • logger:一个兼容 PSR-3 的日志接口

Taproot\Authentication\client()

client() 实现了用户使用他们的域登录您的应用程序并可选地授予它权限(例如使用 micropub 向他们的网站发布新内容的逻辑和路由)。

它返回一个准备就绪的路由集合,可以在您想要的任何位置挂载,包含以下路由

  • /login/(indieauth.login)—向此 URL 发送 POST 请求,包含必需的“me”参数和可选的“next”参数以启动登录过程
  • /authorize/(indieauth.authorize)—用户授权服务器在成功授权后重定向到的 URL。检查详细信息并设置记住我 cookie
  • /logout/(indieauth.logout)—在登录状态下向此 URL 发送 POST 请求(可选的“next”参数),以注销并删除记住我 cookie。
<?php

use Taproot\Authentication;

$app->mount('/', Authentication\client($app));

成功登录后,client() 在用户的浏览器上设置一个记住我 cookie,用户可以在未来的请求中识别自己。默认情况下,cookie 的内容只是一个包含他们信息的数组,已加密,但如果您希望使用其他形式的存储,您可以传递 data -> cookie 和 cookie -> data 函数到 client(),例如:

<?php

use Taproot\Authentication;

$app->mount('/', Authentication\client($app, function (array $data) {
    return storeInDatabase($data);
}, function ($token) {
    return fetchFromDatabase($token);
}));

如果预请求处理器在请求中找到记住我 cookie,则将其转换为包含当前用户信息的数组,并将其添加到 $request->attributes 下的 indieauth.client.token 中。

此数组将始终具有一个me属性,该属性是用户登录的URL。此外,根据用户的登录方式、是否拥有micropub端点以及授予您的权限,它可能还有其他属性。

这是在控制器中典型使用令牌的方法

<?php

function ($request) {
    $token = $request->attributes->get('indieauth.client.token', null);
    if ($token !== null) {
      // User is logged in as $token['me']
      if (!empty($token['access_token']) and !empty($token['micropub_endpoint'])) {
        // The user has granted this app privileges detailed in $token['scope'], which can be carried out by sending
        // requests to $token['micropub_endpoint'] with $token['access_token']
        // Now you might check that the “post” scope is granted, and create some new content on their site (pseudocode):
        if (in_array('post', explode($scope, ' '))) {
          micropub_post($token['micropub_endpoint'], $token['access_token'], $postDetails);
        }
      } else {
        // The user has logged in using the basic indieauth flow — we know that they’re authenticated as $token['me'],
        // but they haven’t granted us any permissions.
      }
    }
};

要程序化地注销用户,在发送响应之前调用$app['indieauth']->logoutResponse($response)

client()不需要上述之外的其他服务,但以下服务可以覆盖默认设置

  • indieauth.url:如果用户尝试登录但找不到授权服务器,则回退到使用此服务器。默认为'https://indieauth.com'
  • indieauth.cookiename:用于记住当前用户的cookie的名称。_random将附加到此以实现随机状态持久化。默认为'indieauth_token'。
  • indieauth.cookielifetime:indieauth remember-me cookie的生存期,以秒为单位。默认为60天。
  • indieauth.loginredirecturl:如果登录尝试中没有给出“next”POST参数,则重定向到此URL。如果未设置,则重定向到$request->getHttpHost()
  • indieauth.clientid:用于识别此indieauth应用的字符串。如果未设置,则默认为$request->getHttpHost()
  • indieauth.securecookie:布尔值,表示是否将认证过程和令牌cookie设置为仅HTTPS。默认为true,仅在开发时关闭。

Taproot\Authentication\server()

server()创建事件处理器和路由,实现令牌提供者和资源服务器(即micropub端点,客户端应用可以代表用户在此处发布帖子)。

令牌端点仅支持单个用户登录。他们的URL必须在$app['owner']['url']中定义。建议使用$app['owner']作为存储有关站点所有者信息的地方,以及授权目的,例如。

$app['owner'] = [
    'name' => 'Owner Name',
    'url' => 'https://example.com',  // Only this field is required for the token endpoint to function.
    'photo' => 'https://example.com/photo.jpg'
];

它返回一个准备就绪的路由集合,可以将其挂载在任何地方,包含以下路由

  • /token/ (indieauth.token) — 客户端将包含加密状态的一组详细信息POST到此URL,以获取访问令牌。
<?php

use Taproot\Authentication;

$app->mount('/', Authentication\server($app);

在授权过程中,服务器为客户端应用创建一个访问令牌,授予他们某些权限(范围)。然后,当客户端应用使用访问令牌进行请求时,预请求监听器会捕获它们,并在$request对象上标注有关用户和“登录”客户端的信息。

这是在控制器中的典型用法——例如,micropub端点

<?php

function ($request) {
    $token = $request->attributes->get('indieauth.server.token', null);
    if ($token !== null) {
        // The request is authenticated, made by $token['client_id'] on behalf of $token['me'] (guaranteed to be a valid URL).
        // $token['date_issued'] is a string containing the ISO8601-formatted datetime the token was issued on.
        if (in_array('post', explode($token['scope'], ' '))) {
            // The user granted this app the “post” permission, so we can go ahead and take other data in $request and make a new post.
            newPost($request->request->all());
        }
    }
};

client()类似,默认情况下server()在访问令牌和它们的数据之间进行映射,但不会将它们保存到持久存储中——访问令牌仅仅是数组的加密形式,然后进行解密。这很简单,但存储访问令牌数据持久化有一些优点——例如,列出授权应用并允许它们被吊销。

您可以使用与client()完全相同的方式定义自己的令牌 -> 数据和数据 -> 令牌函数。

<?php

use Taproot\Authentication;

$app->mount('/', Authentication\server($app, function (array $data) {
    return saveData($data);
}, function ($token) {
    return fetchDataForToken($token);
}));

有问必答

一个应用可以既是客户端又是服务器吗?

当然可以!实际上,在代码被分成客户端和服务器端代码并打包之前,这两个部分共享相同的路由集合和前后端监听器。只需简单地挂载并设置两个路由集合。

这个库可以在Silex之外使用吗?

它最适合与Silex一起使用,但经过一些小的修改,可以轻松地适应任何使用Symfony HTTP Kernel的项目——如果您想让它工作,请提出一个问题。

另外,您可以查看 indieweb/indieauth-client,这是Aaron Parecki的优秀库,其中taproot/authentication只是一个薄包装。

贡献 + 测试

欢迎贡献(尤其是错误报告和安全审查)!请在这里提出问题,或者ping barnabywalters在indiewebcamp的IRC频道上。

截至版本0.1.0,只有一个测试套件的框架——我计划编写全面的函数测试,使用模拟应用程序,但这需要时间,代码已经在waterpigs.co.uk上投入日常使用。

变更日志

v0.1.0 2014-04-09

  • 从Taproot提取的初始版本
  • 将混乱的代码拆分成定义良好的客户端应用程序和资源服务器部分
  • 初始文档
  • 测试套件的框架