innobyte/token-bundle

A Symfony2 Bundle实现基于访问的令牌系统,具有生成、验证和消费机制。

安装量: 7,204

依赖关系: 0

建议者: 0

安全性: 0

星标: 0

关注者: 10

分支: 2

开放性问题: 0

类型:symfony-bundle

2.1.2 2022-01-17 11:36 UTC

This package is not auto-updated.

Last update: 2024-09-28 17:17:51 UTC


README

TokenBundle的目标是提供一种验证用户采取的措施的方法。

通过使用散列来实现验证,例如,可以嵌入在URL中,无论是电子邮件还是页面内生成的即时链接。

安装

composer.json - 安装捆绑包

"require": {
    "innobyte/token-bundle": "~1.1",
},

AppKernel.php - 注册捆绑包

$bundles数组中添加以下行

new Innobyte\TokenBundle\InnobyteTokenBundle(),

config.yml - 添加捆绑映射

在实体管理器(此处为"local")下添加捆绑的映射。注意:"default"是实体管理器的默认名称,如果没有指定其他名称。

doctrine:
    ...
    orm:
        ...
        entity_managers:
            local:
                ...
                mappings:
                    ...
                    InnobyteTokenBundle: ~

parameters.yml - 添加实体管理器名称

添加实体管理器名称(此处为"local")- 在上一步中放入映射的那个。如果没有提供,将使用"default"。注意:只有当实体管理器名称不是"default"时才必须指定。否则,可以完全省略此步骤。

innobyte_token:
    entity_manager: local

更新模式

首先,运行app/console doctrine:schema:update --em=default --dump-sql来查看生成的SQL。

然后,运行app/console doctrine:schema:update --em=default --force在数据库上运行查询。

使用方法

生成令牌

$token = $this->get('innobyte_token')->generate(
    'scope',
    'owner_type',
    123,                       // owner_id
    1,                         // number of uses - optional
    new \DateTime('+1 day'),   // expiry time - optional
    array('author' => 'admin') // additional data to check against - optional
);

// use hash (embed in a link/email etc.)
$hash = $token->getHash();

验证令牌并消费它

try {
    $this->get('innobyte_token')->consume(
        '19debf971fb937853d77fca8fd3bb775',
        'scope',
        'owner_type',
        123            // owner_id
    );
} catch (\Innobyte\TokenBundle\Exception\TokenNotFoundException $e) {
    echo 'cannot find Token';
} catch (\Innobyte\TokenBundle\Exception\TokenInactiveException $e) {
    echo 'handle explicit disabled token here';
} catch (\Innobyte\TokenBundle\Exception\TokenConsumedException $e) {
    echo 'handle over-used token here';
} catch (\Innobyte\TokenBundle\Exception\TokenExpiredException $e) {
    echo 'handle expired token here';
} catch (\Innobyte\TokenBundle\Exception\TokenException $e) {
    // or, alternately, you can catch all token-related exceptions
    echo 'handle all token-related exceptions';
}

echo 'Token is valid. Token is valid. Perform logic here.';

获取令牌并手动验证和消费它

$token = $this->get('innobyte_token')->get(
    '5c15e262c692dbaac75451dcb28282ab',
    'scope',
    'owner_type',
    123            // owner_id
);

// if wrong link or disabled/overused token
if (!$this->get('innobyte_token')->isValid($token)) {
    echo 'Handle invalid token here';
}

// or even more explicit
if (!$token instanceof \Innobyte\TokenBundle\Entity\Token) {
    echo 'handle invalid token here';
} else {
    // manually mark the usage
    try {
        $this->get('innobyte_token')->consumeToken($token);
    } catch (\LogicException $e) {
        echo 'cannot consumed Token because it is not managed';
    }

    echo 'Token is valid. Perform logic here.';
}

无效化

对于无效化,有与"消费"类似的方法:"invalidate"(禁用令牌)

try {
    $this->get('innobyte_token')->invalidate(
        '5c15e262c692dbaac75451dcb28282ab',
        'scope',
        'owner_type',
        123            // owner_id
    );
} catch (\Innobyte\TokenBundle\Exception\TokenNotFoundException $e) {
    echo 'Handle Token not found here';
}

if (!$token instanceof \Innobyte\TokenBundle\Entity\Token) {
    echo 'Handle invalid token here';
} else {
    try {
        $this->get('innobyte_token')->invalidateToken($token);
    } catch (\LogicException $e) {
        echo 'Cannot consume Token because it is not managed';
    }
}

高级验证

在执行标准Token验证后,可以使用其他数据来验证其他条件。

// first, generate the Token
$token = $this->get('innobyte_token')->generate(
    'scope',
    'owner_type',
    123,                       // owner_id
    1,                         // number of uses - optional
    new \DateTime('+1 hour'),   // expiry time - optional
    array('ip' => $request->getClientIp()) // additional data to check against - optional
);

// use hash (embed in a link/email etc.)
$hash = $token->getHash();

// then, validate it
$token = $this->get('innobyte_token')->get(
    $hash,
    'scope',
    'owner_type',
    123            // owner_id
);

// if wrong link or disabled/overused token
if (!$this->get('innobyte_token')->isValid($token)) {
    echo 'Handle invalid token here';
}

// additional validation by IP
$additionalData = $token->getData();
if ($additionalData['ip'] != $request->getClientIp()) {
    echo 'Handle invalid token here';
}

单元测试

不要忘记在config_test.yml中将数据库凭据覆盖为测试数据库的凭据。示例

parameters:
    database_host: 127.0.0.1
    database_port: null
    database_name: test_db
    database_user: root
    database_password: 123

要运行测试,执行

phpunit -c app/ vendor/innobyte/token-bundle/Innobyte/TokenBundle/Tests/