hyvor/helper-laravel

HYVOR应用的内部包

1.1.3 2024-08-05 12:22 UTC

README

本包为Laravel的HYVOR应用提供以下功能

  • 认证(带有模拟提供者)
  • HTTP助手
  • 媒体路由
  • 国际化
  • 组件API

安装

composer require hyvor/internal

Auth

此库为以下提供者提供统一的认证系统

  • HYVOR
  • OpenID Connect
  • 模拟(用于测试)

配置

支持以下环境变量。请参阅 config.php 以获取配置选项。环境变量应在 .env 文件中设置。

用户数据

AuthUser 类用于表示用户。它有以下属性

  • int $id - 用户ID
  • string $name - 用户名
  • string $email - 用户电子邮件
  • ?string $username - 用户用户名(仅限HYVOR)
  • ?string $picture_url - 用户的图片URL
  • ?string $location - 用户的地点
  • ?string $bio - 用户的简介
  • ?string $website_url - 用户的网站URL
  • ?string $sub - 用户的sub(仅限OpenID Connect)
<?php
use Hyvor\Internal\Auth\AuthUser;

// new instance
new AuthUser(
    id: $id, 
    name: $name, 
    ...
);

// from array
AuthUser::fromArray([
    'id' => $id,
    'name' => $name
])

获取数据

获取用户数据应始终使用API调用而不是在应用程序级查询中使用SQL连接,即使使用OpenID Connect也是如此。这是因为HYVOR用户数据始终存储在外部数据库中。

使用以下方法通过用户ID、电子邮件或用户名获取数据

<?php
use Hyvor\Internal\Auth\AuthUser;

AuthUser::fromId($id);
AuthUser::fromIds($ids);

AuthUser::fromEmail($email);
AuthUser::fromEmails($emails);

AuthUser::fromUsername($username);
AuthUser::fromUsernames($usernames);

认证检查

检查用户是否已登录

use Hyvor\Internal\Auth\Auth;

// AuthUser|null
$user = Auth::check();

if ($user) {
    // user is logged in
}

重定向

程序性重定向

使用以下方法获取重定向到登录、注册和注销页面的方法

use Hyvor\Internal\Auth\Auth;

$loginUrl = Auth::login();
$signupUrl = Auth::signup();
$logoutUrl = Auth::logout();

默认情况下,用户在登录或注销后将重定向到当前页面。您还可以设置 redirect 参数,在登录或注销后将用户重定向到特定页面

use Hyvor\Internal\Auth\Auth;

$loginUrl = Auth::login('/console');
// or full URL
$loginUrl = Auth::login('https://talk.hyvor.com/console');

HTTP重定向

以下路由被添加到应用程序以进行HTTP重定向

  • /api/auth/login
  • /api/auth/signup
  • /api/auth/logout

所有端点都支持 redirect 参数,用于在登录或注销后将用户重定向到特定页面/URL。

测试

在测试中,提供者始终设置为 fakeFakeProvider 总是为所有请求的ID、电子邮件和用户名生成假数据。这对于测试很有用。您还可以为 FakeProvider 设置用户数据库,以便为特定用户返回特定数据,如下所示

use Hyvor\Internal\Auth\Providers\Fake\FakeProvider;

it('adds names to the email', function() {

    // set the database of users
    FakeProvider::databaseSet([
        [
            'id' => 1,
            'name' => 'John Doe',
        ]
    ]);
    
    // send email to user ID 1
    // then assert
    expect($email->body)->toContain('John Doe');

});
  • FakeProvider::databaseSet($database) - 设置用户数据库(集合)。
  • FakeProvider::databaseAdd($user) - 向数据库添加用户。
  • FakeProvider::databaseClear() - 清除数据库。这应该在每个测试用例(tearDown)之后调用。

当设置数据库时,FakeProvider 将仅从该数据库返回用户数据。这对于测试以下场景很有用

  • 当找不到用户时(设置空数据库)。
  • 当需要特定用户的具体详细信息时(例如,如上例中的名称、电子邮件等)。

在大多数其他情况下,您应该能够使用模拟提供者而不设置数据库。因为自动为所有用户生成假数据,所以在每个测试用例之前不需要初始化数据库。但是请注意,用户数据在每个测试用例中都会有所不同。

HTTP

本库提供了一些处理HTTP请求的辅助工具。

异常

HttpException

使用 Hyvor\Internal\Http\Exceptions\HttpException 抛出HTTP异常。在大多数情况下,此错误将通过JSON响应发送给客户端。因此,仅在中间件和控制器中使用(绝不在领域中使用)。消息中绝不要共享敏感信息。

use Hyvor\Internal\Http\Exceptions\HttpException;

throw new HttpException('User not found', 404);

中间件

身份验证中间件

使用 Hyvor\Internal\Http\Middleware\AuthMiddleware 为路由要求身份验证。

use Hyvor\Internal\Http\Middleware\AuthMiddleware;

Route::get()->middleware(AuthMiddleware::class);

如果用户未登录,将抛出状态码为401的 HttpException。如果用户已登录,将在服务容器中添加一个 AccessAuthUser 对象(继承自 AuthUser),可以使用以下方式使用:

use Hyvor\Internal\Http\Middleware\AccessAuthUser;

class MyController 
{
    public function index(AccessAuthUser $user) {
        // $user is an instance of AccessAuthUser (extends AuthUser)
    }
}

function myFunction() {
    $user = app(AccessAuthUser::class);
}

路由

以下是本库添加的路由列表

  • POST /api/auth/check - 返回已登录用户或null。
  • GET /api/auth/login - 重定向到登录页面。
  • GET /api/auth/signup - 重定向到注册页面。
  • GET /api/auth/logout - 重定向到注销页面。

模型

HasUser 特性

您可以将 Hyvor\Internal\Auth\HasUser 特性添加到任何模型中,以向其添加一个 user() 方法。此方法返回 AuthUser 对象,使用模型的 user_id 列表。

class Post extends Model
{
    use HasUser;
}

国际化

本库提供了一些国际化处理辅助工具。在HYVOR应用中,大多数时候在客户端使用字符串,但在某些情况下(如电子邮件)您可能需要在后端翻译字符串。类似于我们的设计系统,我们使用ICU消息格式。因此,您可以在前端和后端之间共享相同的翻译。

所有JSON翻译文件应放置在配置文件中设置的目录中。默认目录是 resources/lang。文件名应该是语言代码(例如 en-US.json)。文件应是一个JSON对象,其键是消息ID,值是翻译。也支持嵌套键。区域设置是从目录中的文件加载的。

{
    "welcome": "Welcome to HYVOR",
    "email": "Your email is {email}.",
    "signup": {
        "title": "Sign Up"
    }
}

用法

use Hyvor\Internal\Internationalization\Strings;

$strings = new Strings('en-US');
$welcome = $strings->get('welcome');
$email = $strings->get('email', ['email' => 'me@hyvor.com']);
$signupTitle = $strings->get('signup.title');

区域设置将与最接近的区域设置匹配。例如,如果您有以下区域设置

  • en-US
  • fr-FR
  • es
new Strings('en');; // locale -> `en-US`
new Strings('en-GB'); // locale -> `en-US`
new Strings('fr-FR'); // locale -> `fr-FR`
new Strings('fr'); // locale -> `fr-FR`
new Strings('es-ES'); // locale -> `es`

您还可以使用 ClosestLocale 类获取给定区域设置的最近区域设置。

use Hyvor\Internal\Internationalization\ClosestLocale;

ClosestLocale::get('en', ['en-US', 'fr-FR', 'es']); // returns `en-US`

I18n 单例类是管理应用中区域设置的基类。

use Hyvor\Internal\Internationalization\I18n;

$i18n = app(I18n::class);

$i18n->getAvailableLocales(); // ['en-US', 'fr-FR', 'es', ...]
$i18n->getLocaleStrings('en-US'); // returns the strings from the JSON file as an array
$i18n->getDefaultLocaleStrings(); // strings of the default locale

媒体

本库为您的应用添加了 /api/media/{path} 路由。此路由将从默认存储磁盘提供/流式传输文件。这使得从同一域名提供文件变得容易。