autn/gcl-users

Laravel 用户与角色包

安装: 15

依赖: 0

建议者: 0

安全: 0

星星: 2

关注者: 2

分支: 1

开放问题: 0

类型:项目

v2.2.1 2016-03-31 09:43 UTC

README

Build Status

本模块使用 JWTAuth 和 ENTRUST 库

  1. https://github.com/tymondesigns/jwt-auth (JSON Web Token)
  2. https://github.com/Zizaco/entrust (基于角色的权限)
  3. https://github.com/php-soft/laravel-users (用户管理器)

1. 安装

通过 composer 安装 - 编辑你的 composer.json 文件以添加包。

"require": {
    // ...
    "zizaco/entrust": "dev-laravel-5",
    "autn/gcl-users": "2.x"
}

版本兼容性

然后,在终端运行 composer update 来引入它。完成此操作后,您需要在 app.php 配置文件中的 providers 数组中添加服务提供者,如下所示

'providers' => [
    // ...
    PhpSoft\ArrayView\Providers\ArrayViewServiceProvider::class,
    Gcl\GclUsers\Providers\UserServiceProvider::class,
    Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class,
    Zizaco\Entrust\EntrustServiceProvider::class,
    Baum\Providers\BaumServiceProvider::class,
]

接下来,也在 app.php 配置文件中,在 aliases 数组下,您可能想添加门面。

'aliases' => [
    // ...
    'JWTAuth'   => Tymon\JWTAuth\Facades\JWTAuth::class,
    'JWTFactory'=> Tymon\JWTAuth\Facades\JWTFactory::class,
    'Entrust'   => Zizaco\Entrust\EntrustFacade::class,

您可以使用以下命令发布配置

$ php artisan vendor:publish --provider="Gcl\GclUsers\Providers\UserServiceProvider"

别忘了在 jwt 配置文件中设置一个密钥!

我包含了一个辅助命令来生成密钥,如下所示

$ php artisan jwt:generate

这将生成一个新的随机密钥,它将被用于签名您的令牌。

2. 迁移和填充

现在生成迁移

$ php artisan gcl-users:migrate

它将生成 <timestamp>_entrust_setup_tables.php 迁移。您现在可以使用 artisan migrate 命令运行它

$ php artisan migrate

使用命令运行填充器

$ php artisan db:seed --class=UserModuleSeeder

注意:在使用 UserTrait 之前运行填充器,在你的现有 App\User 模型中,按照以下 3.2 步骤操作

3. 使用

3.1. 使用 JSON Web Token 进行认证

您需要将类 App\User 修改为从 Gcl\GclUsers\Models\User 继承,如下所示

namespace App;

// ...
use Illuminate\Auth\Authenticatable;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Gcl\GclUsers\Models\User as GclUser;

class User extends GclUser implements AuthenticatableContract, AuthorizableContract, CanResetPasswordContract
{
    use Authenticatable, CanResetPassword;

    // ...

    // You need allows fill attributes as follows
    protected $fillable = [
        'name',
        'email',
        'password',
        'username',
        'location',
        'country',
        'biography',
        'occupation',
        'website',
        'image',
        'birthday',
        'gender'
    ];

    // ...
}

app/Http/Kernel.php 中移除中间件

  • \App\Http\Middleware\EncryptCookies::class
  • \App\Http\Middleware\VerifyCsrfToken::class

app/Http/Kernel.php 中添加路由中间件

protected $routeMiddleware = [
    // ...
    'jwt.auth' => \Gcl\GclUsers\Middleware\Authenticate::class,
    'jwt.refresh' => \Tymon\JWTAuth\Middleware\RefreshToken::class,
];

app/Http/routes.php 中添加路由

Route::post('/auth/login', '\Gcl\GclUsers\Controllers\AuthController@login');

Route::group(['middleware'=>'jwt.auth'], function() {
    Route::post('/auth/logout', '\Gcl\GclUsers\Controllers\AuthController@logout');
    Route::get('/me', '\Gcl\GclUsers\Controllers\UserController@authenticated');
    Route::patch('/me', '\Gcl\GclUsers\Controllers\UserController@update');
    Route::put('/me/password', '\Gcl\GclUsers\Controllers\PasswordController@change');
});

Route::post('/passwords/forgot', '\Gcl\GclUsers\Controllers\PasswordController@forgot');
Route::post('/passwords/reset', '\Gcl\GclUsers\Controllers\PasswordController@reset');
Route::group(['middleware'=>'routePermission'], function() {
    Route::get('/users/trash', '\Gcl\GclUsers\Controllers\UserController@index');
    Route::post('/users', '\Gcl\GclUsers\Controllers\UserController@store');
    Route::get('/users/{id}', '\Gcl\GclUsers\Controllers\UserController@show');
    Route::get('/users', '\Gcl\GclUsers\Controllers\UserController@index');
    Route::delete('/users/{id}', '\Gcl\GclUsers\Controllers\UserController@destroy');
    Route::post('/users/{id}/trash', '\Gcl\GclUsers\Controllers\UserController@moveToTrash');
    Route::post('/users/{id}/restore', '\Gcl\GclUsers\Controllers\UserController@restoreFromTrash');
    Route::patch('/users/{id}', '\Gcl\GclUsers\Controllers\UserController@update');
    Route::post('/users/{id}/block', '\Gcl\GclUsers\Controllers\UserController@block');
    Route::post('/users/{id}/unblock', '\Gcl\GclUsers\Controllers\UserController@unblock');
    Route::post('/users/{id}/roles', '\Gcl\GclUsers\Controllers\UserController@assignRole');
    Route::get('/users/{id}/roles', '\Gcl\GclUsers\Controllers\RoleController@indexByUser');

    Route::get('/roles', '\Gcl\GclUsers\Controllers\RoleController@index');
    Route::get('/roles/{id}', '\Gcl\GclUsers\Controllers\RoleController@show');
    Route::post('/roles', '\Gcl\GclUsers\Controllers\RoleController@store');
    Route::patch('/roles/{id}', '\Gcl\GclUsers\Controllers\RoleController@update');
    Route::delete('/roles/{id}', '\Gcl\GclUsers\Controllers\RoleController@destroy');

    Route::get('/nodePermission', '\Gcl\GclUsers\Controllers\NodePermissionController@index');
    Route::post('/nodePermission', '\Gcl\GclUsers\Controllers\NodePermissionController@store');
    Route::patch('/nodePermission/{id}', '\Gcl\GclUsers\Controllers\NodePermissionController@updateInfo');
    Route::delete('/nodePermission/{id}', '\Gcl\GclUsers\Controllers\NodePermissionController@destroy');
    Route::post('/nodePermission/tree', '\Gcl\GclUsers\Controllers\NodePermissionController@updateTree');
    Route::get('/roles/{id}/permission', '\Gcl\GclUsers\Controllers\NodePermissionController@getRolePerm');
    Route::get('/roles/{id}/allPermission', '\Gcl\GclUsers\Controllers\NodePermissionController@checkAllPerm');
    Route::post('/roles/{id}/permission', '\Gcl\GclUsers\Controllers\NodePermissionController@storePermToRole');
    Route::get('/nodePermission/{id}/route', '\Gcl\GclUsers\Controllers\PermissionRouteController@index');
    Route::post('/nodePermission/{id}/route', '\Gcl\GclUsers\Controllers\PermissionRouteController@store');
    Route::delete('/permissionRoute/{id}', '\Gcl\GclUsers\Controllers\PermissionRouteController@destroy');

    Route::get('/routes', '\Gcl\GclUsers\Controllers\PermissionRouteController@getAllRoutes');
    Route::get('/routesNotTree', '\Gcl\GclUsers\Controllers\PermissionRouteController@getAllRoutesNotTree');
});

注意:您可以将其添加到您的中间件组 api

Apache 似乎会丢弃非 base64 编码的用户/密码组合的授权头。因此,要修复此问题,您可以将以下内容添加到您的 apache 配置中

RewriteEngine On

RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]

或者,您可以通过查询字符串包含令牌

http://api.mysite.com/me?token={yourtokenhere}

3.2. 基于角色的权限

在您的现有 App\User 模型中使用 UserTrait 特性。例如

namespace App;

// ...
use Gcl\GclUsers\Models\UserTrait;

class User extends GclUser implements AuthenticatableContract, AuthorizableContract, CanResetPasswordContract
{
    use UserTrait, Authenticatable, CanResetPassword; // add this trait to your user model
    // ...
}

创建 RolePermission

// create role admin (default this role has been created on UserModuleSeeder)
$admin = new Role();
$admin->name         = 'admin';
$admin->display_name = 'User Administrator'; // optional
$admin->description  = 'User is allowed to manage and edit other users'; // optional
$admin->save();

// role attach alias
$user->attachRole($admin); // parameter can be an Role object, array, or id

// or eloquent's original technique
$user->roles()->attach($admin->id); // id only

// create permission
$createPost = new NodePermission();
$createPost->name         = 'create-post';
$createPost->display_name = 'Create Posts'; // optional
$createPost->description  = 'create new blog posts'; // optional
$createPost->parent_id    = 1 // optional
$createPost->save();

$admin->attachPermission($createPost);
// equivalent to $admin->perms()->sync(array($createPost->id));

现在我们可以通过以下方式简单地检查角色和权限

$user->hasRole('owner');   // false
$user->hasRole('admin');   // true
$user->can('edit-user');   // false
$user->can('create-post'); // true

hasRole()can() 都可以接收一个要检查的角色和权限数组

$user->hasRole(['owner', 'admin']);       // true
$user->can(['edit-user', 'create-post']); // true

3.3. 忘记密码

要发送忘记密码邮件,

  • 您需要在 config\mail.php 中添加发件人的地址和名称,如下所示
'from' => ['address' => 'no-reply@example.com', 'name' => 'System'],
  • 您需要在 resources\views\emails 文件夹中创建电子邮件视图:创建 password.blade.php 文件,内容如下
<h3>You are receiving this e-mail because you requested resetting your password to domain.com</h3>
Please click this URL to reset your password: <a href="http://domain.com/passwords/reset?token={{$token}}">http://domain.com/passwords/reset?token={{$token}}</a>

您可以更改此视图的内容以供使用。

另一种方法,您可以使用其他视图和配置 password.emailconfig\auth.php

    'password' => [
        'email' => 'emails.password',
        'table' => 'password_resets',
        'expire' => 60,
    ],

3.4. 中间件

Gcl\GclUsers\Middleware\RoutePermission

此中间件用于根据数据库动态检查路由的权限。

app/Http/Kernel.php 中添加路由中间件

protected $routeMiddleware = [
    // ...
    'routePermission' => \Gcl\GclUsers\Middleware\RoutePermission::class,
];

使用

Route::group(['middleware'=>'routePermission'], function() {
    Route::post('/blog', function () {
        //
    });
});

如下所示为路由要求权限

// require permissions or roles
Gcl\GclUsers\Models\RoutePermission::setRoutePermissionsRoles(2, '/blog', 'POST');

Gcl\GclUsers\Middleware\Validate

此中间件用于检查使用此包的不同应用程序中的字段验证。

app/Http/Kernel.php 中添加路由中间件

protected $routeMiddleware = [
    // ...
    'validate'   => \Gcl\GclUsers\Middleware\Validate::class,
];

使用

Route::post('/user', ['middleware'=>'validate: App\Http\Validators\UserValidate',
    function () {
        //
    }
]);

使用 App\Http\Validators\UserValidate,这是一个你需要在路由中声明的类。此类用于声明验证规则。

你还可以使用其他类来声明应用程序中的验证规则,但必须实现 Gcl\GclUsers\Contracts\Validator 类。

例如,我在 App\Http\Validators\UserValidate 类中声明规则如下

use Gcl\GclUsers\Contracts\Validator;

/**
 * User Validate
 *
 * return array
 */
class UserValidate implements Validator
{
    /**
     * Custom validator
     *
     * @return boolean
     */
    public static function boot($request)
    {

        IlluminateValidator::extend('validate_name', function($attribute, $value, $parameters) {

                return $value == 'validate_name';
            }, 'The name is in valid.'
        );
    }

    /**
     * Declare rules
     *
     * @return array
     */
    public static function rules()
    {
        return [
            'name'     => 'required|max:255|validate_name',
            'email'    => 'required|email',
            'password' => 'required|confirmed|min:6'
        ];
    }
}

在这里,你将在 rules() 函数中声明你想要验证的字段。你还可以通过在 boot() 函数中声明来自定义你想要验证的字段。