sentinel 使用_使用Sentinel消除用户授权的痛苦

sentinel 使用

Most non-basic multi-user applications need some roles and permission levels. If you ever used WordPress, you must have noticed that they have a super admin, admin, editor, author, etc. Simplifying the development and integration of a permission system is what Cartalyst’s Sentinel package is trying to accomplish. The package provides an API for dealing with users, groups, permissions, etc. In this article, we’ll use it to create a small demo app.

大多数非基本的多用户应用程序都需要某些角色和权限级别。 如果您曾经使用过WordPress,那么您一定已经注意到他们具有超级管理员,管理员,编辑者,作者等。简化权限系统的开发和集成是Cartalyst的Sentinel软件包试图实现的目标。 该包提供了一个用于处理用户,组,权限等的API。在本文中,我们将使用它来创建一个小型演示应用程序。

Cartalyst Sentinel

环境设定 (Environment Setup)

For our sample application in this tutorial, we will be using the Slim micro-framework and Vagrant. You can check out the final demo on Github to see the result. Let’s start by first requiring the necessary packages:

对于本教程中的示例应用程序,我们将使用Slim微框架Vagrant 。 您可以在Github上查看最终的演示以查看结果。 让我们首先要求必要的软件包:

composer require slim/slim:~2.0
composer require twig/twig:~1.*
composer require cartalyst/sentinel:2.0.*

Sentinel suggests installing Illuminate Eloquent, Illuminate Events, Symfony Http Foundation and ircmaxell password-compat so let’s add those to the project.

Sentinel建议安装Illuminate EloquentIlluminate EventsSymfony Http Foundationircmaxell password-compat,因此让我们将其添加到项目中。

composer require illuminate/database illuminate/events symfony/http-foundation ircmaxell/password-compat

Because working with users, groups and permissions requires some database interaction, we need to create our database with the necessary tables. If you are using Laravel you can install the database using the migrate command.

因为使用用户,组和权限需要一些数据库交互,所以我们需要使用必要的表来创建数据库。 如果您使用的是Laravel,则可以使用migration命令安装数据库。

php artisan vendor:publish --provider="Cartalyst\Sentinel\Laravel\SentinelServiceProvider"
php artisan migrate

If not, you’ll have to do it manually using the following steps. You can read more about database installation in the documentation.

如果没有,则必须使用以下步骤手动进行。 您可以在文档中阅读有关数据库安装的更多信息。

  • Open the vendor/cartalyst/sentinel/schema/mysql.sql, add use DATABASENAME; at the top of the file and save.

    打开vendor/cartalyst/sentinel/schema/mysql.sql ,添加use DATABASENAME; 在文件顶部并保存。

  • Feed your file to MySQL using the command mysql -u root -p < vendor/cartalyst/sentinel/schema/mysql.sql and enter the password if necessary, or just import the file using your favorite SQL editor / inspector (like PhpMyAdmin, Sequel Pro, etc).

    使用命令mysql -u root -p < vendor/cartalyst/sentinel/schema/mysql.sql将文件提供给MySQL,并在需要时输入密码,或者仅使用您喜欢SQL编辑器/检查器(如PhpMyAdmin,Sequel)导入文件专业版等)。

Finally, let’s bootstrap our app with a public/index.php file:

最后,让我们使用public/index.php文件引导我们的应用程序:

<?php

require_once __DIR__.'/../vendor/autoload.php';

$app = new \Slim\Slim();
//register bindings

include_once __DIR__.'/../app/bootstrap/container.php';

include_once __DIR__.'/../app/routes.php';

$app->run();

容器绑定 (Container Bindings)

Inside our app/bootstrap/container.php we will define our container bindings.

在我们的app/bootstrap/container.php我们将定义容器绑定。

$app->container->twigLoader = new Twig_Loader_Filesystem(__DIR__.'/../views');
$app->container->twig = new Twig_Environment($app->container->twigLoader, array(
    'cache' => false,
));

The $app variable is a Slim container. Since we chose to use Eloquent for our database interactions we need to specify the connection configuration.

$app变量是一个Slim容器。 由于我们选择使用Eloquent进行数据库交互,因此我们需要指定连接配置。

// app/bootstrap/container.php

$capsule = new \Illuminate\Database\Capsule\Manager();
$capsule->addConnection([
    'driver' => 'mysql',
    'host' => 'localhost',
    'database' => 'capsule',
    'username' => 'root',
    'password' => 'root',
    'charset' => 'utf8',
    'collation' => 'utf8_unicode_ci',
]);
$capsule->bootEloquent();

After booting Eloquent, the only part left is to bind Sentinel to the container.

引导Eloquent后,剩下的唯一部分就是将Sentinel绑定到容器。

// app/bootstrap/container.php

$app->container->sentinel = (new \Cartalyst\Sentinel\Native\Facades\Sentinel())->getSentinel();

If you prefer to use static calls, you can use it directly. (Sentinel::authenticate($credentials))

如果您喜欢使用静态呼叫,则可以直接使用它。 ( Sentinel::authenticate($credentials) )

创建角色 (Creating Roles)

The first step is to define our permission groups. We have the admin role which gives the user the permission to create, update and delete users. On the other hand, the user role only gives the permission to update users.

第一步是定义我们的权限组。 我们具有admin角色,该角色授予用户创建,更新和删除用户的权限。 另一方面, user角色仅授予更新用户的权限。

$app->container->sentinel->getRoleRepository()->createModel()->create(array(
    'name'          => 'Admin',
    'slug'          => 'admin',
    'permissions'   => array(
        'user.create' => true,
        'user.update' => true,
        'user.delete' => true
    ),
));

$app->container->sentinel->getRoleRepository()->createModel()->create(array(
    'name'          => 'User',
    'slug'          => 'user',
    'permissions'   => array(
        'user.update' => true
    ),
));

This code is temporary, and can be placed at the bottom of index.php, run once, and then removed. Its only purpose is to create the roles in the database.

这段代码是临时的,可以放在index.php的底部,运行一次,然后删除。 其唯一目的是在数据库中创建角色。

注册页面 (Sign up Page)

We have two options when creating the sign up page. We can either use email confirmation, or directly set the user as validated.

创建注册页面时,我们有两个选择。 我们可以使用电子邮件确认,也可以直接将用户设置为已验证。

// app/routes.php

$app->get('/', function () use ($app) {
    $app->twig->display('home.html.twig');
});

Our home page contains a form and a set of fields for user details (first name, last name, email, password and password confirmation). Check the source code of the view files here.

我们的主页包含一个表单和一组用于用户详细信息(名字,姓氏,电子邮件,密码和密码确认)的字段。 在此处检查视图文件的源代码。

Then, let’s define the POST home route.

然后,让我们定义POST本地路由。

// app/routes.php

$app->post('/', function () use ($app) {
    // we leave validation for another time
    $data = $app->request->post();

    $role = $app->container->sentinel->findRoleByName('User');

    if ($app->container->sentinel->findByCredentials([
        'login' => $data['email'],
    ])) {
        echo 'User already exists with this email.';

        return;
    }

    $user = $app->container->sentinel->create([
        'first_name' => $data['firstname'],
        'last_name' => $data['lastname'],
        'email' => $data['email'],
        'password' => $data['password'],
        'permissions' => [
            'user.delete' => 0,
        ],
    ]);

    // attach the user to the role
    $role->users()->attach($user);

    // create a new activation for the registered user
    $activation = (new Cartalyst\Sentinel\Activations\IlluminateActivationRepository)->create($user);
    mail($data['email'], "Activate your account", "Click on the link below \n <a href='http://vaprobash.dev/user/activate?code={$activation->code}&login={$user->id}'>Activate your account</a>");

    echo "Please check your email to complete your account registration.";
});

After getting the request data and resolving Sentinel from the container, we select the role that we want to assign to the new user. You can query roles by name, slug or by ID. More about that in the documentation. Next, we test to see if the new user is already registered, then we create a new user using the request data, assign it the User role and we create a new activation. The activation process is totally optional, we will talk more about it later. We skipped the validation process here to keep the function simple.

在获取请求数据并从容器中解析Sentinel之后,我们选择要分配给新用户的角色。 您可以按名称,名称或ID查询角色。 有关该文档的更多信息。 接下来,我们测试是否已注册新用户,然后使用请求数据创建新用户,为其分配User角色,然后创建新激活。 激活过程完全是可选的,我们将在后面详细讨论。 为了使功能简单,我们在此处跳过了验证过程。

权限 (Permissions)

The User role gives users the permission to update. But, what if we wanted to add or override some permissions?

User角色授予用户更新权限。 但是,如果我们想添加或覆盖某些权限怎么办?

$user = $app->container->sentinel->create([
    'first_name' => $data['firstname'],
    'last_name' => $data['lastname'],
    'email' => $data['email'],
    'password' => $data['password'],
    'permissions' => [
        'user.update' => false,
        'user.create' => true
    ],
]);

Sentinel has two methods for working with permissions: standard or strict. For the standard method, you can give the user the ability to create new users directly ('user.create': true), but when you want to deny a permission to the role, you just need to give it false on the user’s permissions. The strict method will negate the permission if is set to false anywhere. You can read more about permissions in the documentation.

Sentinel有两种使用权限的方法:标准或严格。 对于标准方法,您可以赋予用户直接创建新用户的能力( 'user.create': true ),但是当您想拒绝该角色的权限时,只需在用户权限上将其设置为false 。 。 如果在任何地方将其设置为false则strict方法将否决该权限。 您可以在文档中阅读有关权限的更多信息。

用户激活 (User Activation)

After saving the user to the database, you’ll need to send the activation link to the user’s email.

将用户保存到数据库后,您需要将激活链接发送到用户的电子邮件。

We have two methods to implement the activation process. The first will send the code and the user ID via email, and the second one will only send the activation code.

我们有两种方法来实现激活过程。 第一个将通过电子邮件发送代码和用户ID,第二个将仅发送激活代码。

// app/routes.php

$app->post('/', function () use ($app) {
    //...

    $activation = (new Cartalyst\Sentinel\Activations\IlluminateActivationRepository)->create($user);
    mail($data['email'], "Activate your account", "Click on the link below \n <a href='http://vaprobash.dev/user/activate?code={$activation->code}&login={$user->id}'>Activate your account</a>");

    echo "Please check your email to complete your account registration.";
});

The create method on the IlluminateActivationRepository will return a database record containing the activation code. Now, we need to create a new route to catch the account validation request.

IlluminateActivationRepository上的create方法将返回包含激活码的数据库记录。 现在,我们需要创建一条新路径来捕获帐户验证请求。

// app/routes.php

$app->get('/user/activate', function () use ($app) {
    $code = $app->request->get('code');
    $login = $app->request->get('login');
    $activation = new Cartalyst\Sentinel\Activations\IlluminateActivationRepository;

    if (!($user = $app->sentinel->findById($login)))
    {
        echo "User not found!";

        return;
    }

    if (!$activation->complete($user, $code))
    {
        if ($activation->completed($user))
        {
            echo 'User is already activated. Try to log in.';

            return;
        }
        echo "Activation error!";

        return;
    }

    echo 'Your account has been activated. Log into your account.';

    return;
});

The first step is to test whether or not the user exists. Then, we attempt to complete the activation. In case of error, we check to see if the user has been already activated.

第一步是测试用户是否存在。 然后,我们尝试完成激活。 如果发生错误,我们将检查用户是否已被激活。

// app/routes.php

$app->get('/user/activate', function () use ($app) {
    $code = $app->request->get('code');

    $activationRepository = new Cartalyst\Sentinel\Activations\IlluminateActivationRepository;
    $activation = Cartalyst\Sentinel\Activations\EloquentActivation::where("code", $code)->first();

    if (!$activation)
    {
        echo "Activation error!";

        return;
    }

    $user = $app->container->sentinel->findById($activation->user_id);

    if (!$user)
    {
        echo "User not found!";

        return;
    }


    if (!$activationRepository->complete($user, $code))
    {
        if ($activationRepository->completed($user))
        {
            echo 'User is already activated. Try to log in.';

            return;
        }

        echo "Activation error!";

        return;
    }

    echo 'Your account has been activated. Log in to your account.';

    return;
});

The first step is to retrieve the activation record using the code parameter, then we grab the user using the user ID from the activation record, and the last part is similar to the first method. You can read more about activation in the documentation. I prefer using the second method for the activation process and I always avoid sending unnecessary details to the user.

第一步是使用code参数检索激活记录,然后使用激活记录中的用户ID捕获用户,最后一部分类似于第一种方法。 您可以在文档中阅读有关激活的更多信息。 我更喜欢在激活过程中使用第二种方法,并且始终避免向用户发送不必要的详细信息。

登录页面 (Login Page)

The login page contains an email field, password, and the user can choose to be remembered.

登录页面包含一个电子邮件字段,密码,用户可以选择被记住。

// app/routes.php

$app->get('/login', function () use ($app) {

    $app->twig->display('login.html.twig');
});

After getting the user email and password we can pass them to the authenticate method. It may throw an exception depending on the error (ThrottlingException, NotActivatedException, etc). You can read more about the authenticate method in the documentation. However, you may have a remember me field to automatically log the user in the future. The authenticateAndRemember method is similar to the authenticate method and sets the remember me parameter to true by default.

获取用户电子邮件和密码后,我们可以将其传递给authenticate方法。 根据错误( ThrottlingExceptionNotActivatedException等),它可能会引发异常。 您可以在文档中阅读有关authenticate方法的更多信息。 但是,您可能会有一个“ remember me字段,以便将来自动登录用户。 authenticateAndRemember方法类似于authenticate方法,默​​认情况下将“记住我”参数设置为true

// app/routes.php

$app->post('/login', function () use ($app) {
    $data = $app->request->post();
    $remember = isset($data['remember']) && $data['remember'] == 'on' ? true : false;

    try {
        if (!$app->container->sentinel->authenticate([
                'email' => $data['email'],
                'password' => $data['password'],
            ], $remember)) {

            echo 'Invalid email or password.';

            return;
        } else {
            echo "You're logged in";

            return;
        }
    } catch (Cartalyst\Sentinel\Checkpoints\ThrottlingException $ex) {
        echo "Too many attempts!";

        return;
    } catch (Cartalyst\Sentinel\Checkpoints\NotActivatedException $ex){
        echo "Please activate your account before trying to log in";

        return;
    }
});

The authenticate method will return the user on success or false on failure, but the important part is that it can throw an exception depending on the enabled checkpoints, which are like middleware that intercept the login process and decide if you can continue or not. In this case, we may have a ThrottlingException in case of abusive login attempts or a NotActivatedException if the user has not been activated yet. You can configure the enabled checkpoints inside vendor/cartalyst/sentinel/src/config in the checkpoints section.

authenticate方法将在成功时返回用户,或者在失败时返回false,但是重要的是它可以根据启用的检查点抛出异常,就像中间件一样,该检查点会拦截登录过程并确定是否可以继续。 在这种情况下,如果滥用登录尝试,则可能会出现ThrottlingException ;如果尚未激活用户,则可能会出现NotActivatedException 。 您可以在“ checkpoints部分的vendor/cartalyst/sentinel/src/config中配置已启用的检查checkpoints

登出 (Logout)

Logging out the current user is really straightforward.

注销当前用户确实非常简单。

// app/routes.php

$app->get('/logout', function () use ($app) {
    $app->container->sentinel->logout();

    echo 'Logged out successfully.';
});

管理员页面 (Admin Page)

Our admin page doesn’t contain any view content. We are just going to test if the user is connected, get the logged in user and then test if he has the required permissions to access the page.

我们的管理页面不包含任何视图内容。 我们将测试用户是否已连接,获取登录用户,然后测试该用户是否具有访问该页面所需的权限。

// app/routes.php

$app->get('/admin/users', function () use ($app) {
    $loggedUser = $app->container->sentinel->check();

    if (!$loggedUser) {
        echo 'You need to be logged in to access this page.';

        return;
    }

    if (!$loggedUser->hasAccess('user.*')) {
        echo "You don't have the permission to access this page.";

        return;
    }

    echo 'Welcome to the admin page.';
});

The check method returns the logged in user or false. If we have a user, we call the hasAccess method with the required permissions. The * alias selects any permission. You can use user.update or user.delete depending on the required permission to access the resource.

check方法返回登录的用户或false 。 如果有用户,则使用所需的权限调用hasAccess方法。 *别名选择任何权限。 您可以根据访问资源所需的权限使用user.updateuser.delete

结语 (Wrapping Up)

The Sentinel package takes out the pain of user permission and role management. It also offers the ability to add in password reminders, password hashers, etc. Be sure to check the documentation for more details, look at the final product on Github, and if you have any questions or comments, don’t hesitate to post them below.

Sentinel软件包消除了用户权限和角色管理的痛苦。 它还提供添加密码提示,密码哈希等的功能。请务必查看文档以获取更多详细信息,查看Github上的最终产品,如果有任何疑问或意见,请随时发布。下面。

翻译自: https://www.sitepoint.com/removing-the-pain-of-user-authorization-with-sentinel/

sentinel 使用

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
©️2021 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值