webpress/user-manager

此包最新版本(3.1.87)没有提供许可证信息。

Laravel / Lumen 的用户组件


README

用户组件包提供了一种方便管理应用程序用户的方式。

安装

Composer

要将此包包含到您的项目中,请运行以下命令。

composer require vicoders/usermanager

包安装完成后,下一步取决于您使用的框架。

服务提供者

Laravel

在您的 config/app.php 文件中,将以下服务提供者添加到 providers 数组的末尾

'providers' => [
    ...
    VCComponent\Laravel\User\Providers\UserComponentProvider::class,
    VCComponent\Laravel\User\Providers\UserComponentRouteProvider::class,
    VCComponent\Laravel\User\Providers\UserComponentEventProvider::class,
],

Lumen

在您的 bootstrap/app.php 文件中添加以下服务提供者。

$app->register(App\Providers\AuthServiceProvider::class);
$app->register(Tymon\JWTAuth\Providers\LumenServiceProvider::class);
$app->register(Dingo\Api\Provider\LumenServiceProvider::class);
$app->register(Prettus\Repository\Providers\LumenRepositoryServiceProvider::class);
$app->register(VCComponent\Laravel\User\Providers\LumenUserComponentProvider::class);

您还需要在 bootstrapp/app.php 中定义 route

$app->router->group([
], function ($router) {
    require __DIR__ . '/../vendor/codersvn/usermanagement/src/routes.php';
});

配置和迁移

Laravel

运行以下命令以发布配置和迁移文件。

php artisan vendor:publish --provider="VCComponent\Laravel\User\Providers\UserComponentProvider"
php artisan vendor:publish --provider="Dingo\Api\Provider\LaravelServiceProvider"
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
php artisan vendor:publish --provider "Prettus\Repository\Providers\RepositoryServiceProvider"

创建表。

php artisan migrate

请删除 Laravel 默认的 users 迁移文件,以避免在运行迁移命令时发生冲突。

config/auth.php 中进行更改。

'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model'  => VCComponent\Laravel\User\Entities\User::class,
    ],
],

Lumen

创建 config/auth.php 文件并添加以下内容。

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Authentication Defaults
    |--------------------------------------------------------------------------
    |
    | This option controls the default authentication "guard" and password
    | reset options for your application. You may change these defaults
    | as required, but they're a perfect start for most applications.
    |
    */

    'defaults' => [
        'guard' => env('AUTH_GUARD', 'api'),
    ],

    /*
    |--------------------------------------------------------------------------
    | Authentication Guards
    |--------------------------------------------------------------------------
    |
    | Next, you may define every authentication guard for your application.
    | Of course, a great default configuration has been defined for you
    | here which uses session storage and the Eloquent user provider.
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | Supported: "session", "token"
    |
    */

    'guards' => [
        'api' => [
            'driver' => 'jwt',
            'provider' => 'users'
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | User Providers
    |--------------------------------------------------------------------------
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | If you have multiple user tables or models you may configure multiple
    | sources which represent each model / table. These sources may then
    | be assigned to any extra authentication guards you have defined.
    |
    | Supported: "database", "eloquent"
    |
    */

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model'  => VCComponent\Laravel\User\Entities\User::class,
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Resetting Passwords
    |--------------------------------------------------------------------------
    |
    | Here you may set the options for resetting passwords including the view
    | that is your password reset e-mail. You may also set the name of the
    | table that maintains all of the reset tokens for your application.
    |
    | You may specify multiple password reset configurations if you have more
    | than one user table or model in the application and you want to have
    | separate password reset settings based on the specific user types.
    |
    | The expire time is the number of minutes that the reset token should be
    | considered valid. This security feature keeps tokens short-lived so
    | they have less time to be guessed. You may change this as needed.
    |
    */

    'passwords' => [
        'users' => [
            'provider' => 'users',
            'table' => 'password_resets',
            'expire' => 60,
        ],
    ],

];

创建以下迁移文件。

php artisan make:migration create_password_resets_table
php artisan make:migration create_users_table
php artisan make:migration create_statuses_table
php artisan make:migration create_user_meta_table

将以下内容添加到相应的迁移文件中

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePasswordResetsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('password_resets', function (Blueprint $table) {
            $table->string('email')->index();
            $table->string('token');
            $table->timestamp('created_at')->nullable();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('password_resets');
    }
}
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('email', 40);
            $table->string('username', 100);
            $table->string('first_name', 100);
            $table->string('last_name', 100);
            $table->string('password', 100);
            $table->dateTime('last_login');
            $table->boolean('email_verified')->default(0);
            $table->integer('status');
            $table->rememberToken();
            $table->timestamps();

        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
}
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateStatusesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('statuses', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name', 20);
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('statuses');
    }
}
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateUserMetaTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('user_meta', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('user_id')->unsigned();
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
            $table->string('key');
            $table->text('value');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('user_meta');
    }
}

创建表。

php artisan migrate

环境

.env 文件中,我们需要一些配置。

API_PREFIX=api
API_VERSION=v1
API_NAME="Your API Name"
API_DEBUG=false

.env 文件中生成 JWT_SECRET

php artisan jwt:secret

现在包已准备好使用。

配置

URL 命名空间

为了避免与您的应用程序的 API 端点重复,该包为其路由提供了默认命名空间 user-management。例如

{{url}}/api/user-management/admin/users

您可以通过修改 .env 文件中的 USER_MANAGEMENT_NAMESPACE 变量来将包的 URL 命名空间更改为您想要的任何内容。

USER_MANAGEMENT_NAMESPACE="your-namespace"

用户模型

您可以通过修改 config/auth.php 使用您自己的 User 模型。

'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model'  => App\Entities\User::class,
    ],
],

您的 User 模型必须具有以下内容。

<?php

namespace App\Entities;

use Illuminate\Auth\Authenticatable;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Database\Eloquent\Model;
// use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Hash;
use VCComponent\Laravel\User\Contracts\UserManagement;
use VCComponent\Laravel\User\Contracts\UserSchema;
use VCComponent\Laravel\User\Notifications\MailResetPasswordToken;
use VCComponent\Laravel\User\Traits\UserManagementTrait;
use VCComponent\Laravel\User\Traits\UserSchemaTrait;
use Prettus\Repository\Contracts\Transformable;
use Prettus\Repository\Traits\TransformableTrait;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Tymon\JWTAuth\Facades\JWTAuth;

class User extends Model implements AuthenticatableContract, JWTSubject, Transformable, UserManagement, UserSchema, CanResetPasswordContract
{
    use Authenticatable,
        TransformableTrait,
        UserManagementTrait,
        UserSchemaTrait,
        // Notifiable,
        CanResetPassword;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'email',
        'username',
        'first_name',
        'last_name',
        'avatar',
    ];

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */
    protected $hidden = [
        'password',
    ];

    /**
     * Get the identifier that will be stored in the subject claim of the JWT.
     *
     * @return mixed
     */
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    /**
     * Return a key value array, containing any custom claims to be added to the JWT.
     *
     * @return array
     */
    public function getJWTCustomClaims()
    {
        return [];
    }

    public function setPasswordAttribute($value)
    {
        $this->attributes['password'] = Hash::make($value);
    }

    public function getEmailVerifyToken()
    {
        return Hash::make($this->email);
    }

    public function sendPasswordResetNotification($token)
    {
        // $this->notify(new MailResetPasswordToken($token));
    }

    public function getToken()
    {
        return JWTAuth::fromUser($this);
    }
}

用户转换器

Laravel

您可以通过修改 config/user.php 使用您自己的 UserTransformer 类。

'transformers' => [
    'user'   => App\Transformers\UserTransformer::class,
],

Lumen

创建 config/user.php 并包含以下内容。

<?php

return [

    'namespace'    => env('USER_MANAGEMENT_NAMESPACE', 'user-management'),

    'transformers' => [
        'user'   => VCComponent\Laravel\User\Transformers\UserTransformer::class,
    ],

];

现在您可以修改 UserTransformer 类。

社交登录

要使用包提供的社交登录 API,您必须将这些配置添加到 config/services.php

'facebook'  => [
    'client_id'     => env('FACEBOOK_CLIENT_ID'),
    'client_secret' => env('FACEBOOK_CLIENT_SECRET'),
    'redirect'      => env('FACEBOOK_CALLBACK_URL'),
],

'google'    => [
    'client_id'     => env('GOOGLE_CLIENT_ID'),
    'client_secret' => env('GOOGLE_CLIENT_SECRET'),
    'redirect'      => env('GOOGLE_CALLBACK_URL'),
],

用户模型

用户模式

默认情况下,该包在 users 表中提供了一些非常基本的字段。在您的应用程序中,您可能需要在 users 表中拥有自己的字段以满足您应用程序的需求。这可以通过包内的 User Meta 系统解决,该系统包含您包含的任何附加字段数据。

该包提供了一种通过 schema() 方法描述您附加字段的方式。在 schema() 中,您需要定义字段的 name、字段 type 和字段验证 rule

您需要做的只是声明您的 User 模型中的 schema() 方法。

public static function schema()
{
    return [
        'address' => [
            'type' => 'string',
            'rule' => ['required']
        ],
        'phone_number' => [
            'type' => 'string',
            'rule' => ['required', 'regex:/^\d+$/', 'min:9', 'max:15']
        ],
    ];
}

用户管理

在您的应用程序中,您可能需要确定用户是否有权访问用户资源。该软件包提供了UserManagementTrait,其中包含授权访问的逻辑。UserMangementTrait包含5个方法:ableToShow()ableToCreate()ableToUpdate()ableToUpdateProfile()ableToDelete()。这些方法将执行检查逻辑,然后返回布尔值。

要使用自己的逻辑覆盖默认逻辑,您只需在您的User模型中声明这些方法即可。

public function ableToUpdateProfile($id)
{
    if ($this->id == $id || $this->isRole('admin')) {
        return true;
    }
    return false;
}

有关这些方法的更多详细信息,请参阅VCComponent\Laravel\User\Traits\UserManagementTrait

API 列表

以下是该软件包提供的API列表。

路由

自定义路由

要使用自己的路由,您需要在config/app.php中移除VCComponent\Laravel\User\Providers\UserComponentRouteProvider

现在您可以手动创建和使用自己的路由。

自定义控制器

您可以使用自己的UserController来自定义API功能。

为了确保您的更改不会破坏其他功能,您的UserController需要扩展VCComponent\Laravel\User\Http\Controller\ApiController,并为管理员控制器使用UserAdminMethods特质,为前端控制器使用UserFrontendMethods特质。

事件

要使用自己的事件,只需在AppServiceProvider文件中将您的事件绑定到软件包提供的接口。

<?php

namespace App\Providers;

use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Event;
use VCComponent\Laravel\User\Contracts\Events\UserCreatedByAdminEventContract;
use VCComponent\Laravel\User\Contracts\Events\UserDeletedEventContract;
use VCComponent\Laravel\User\Contracts\Events\UserEmailVerifiedEventContract;
use VCComponent\Laravel\User\Contracts\Events\UserLoggedInEventContract;
use VCComponent\Laravel\User\Contracts\Events\UserRegisteredBySocialAccountEventContract;
use VCComponent\Laravel\User\Contracts\Events\UserRegisteredEventContract;
use VCComponent\Laravel\User\Contracts\Events\UserUpdatedByAdminEventContract;
use VCComponent\Laravel\User\Contracts\Events\UserUpdatedEventContract;
use App\Events\UserCreatedByAdminEvent;
use App\Events\UserDeletedEvent;
use App\Events\UserEmailVerifiedEvent;
use App\Events\UserLoggedInEvent;
use App\Events\UserRegisteredBySocialAccountEvent;
use App\Events\UserRegisteredEvent;
use App\Events\UserUpdatedByAdminEvent;
use App\Events\UserUpdatedEvent;

class AppServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->bind(UserRegisteredEventContract::class, UserRegisteredEvent::class);
        $this->app->bind(UserEmailVerifiedEventContract::class, UserEmailVerifiedEvent::class);
        $this->app->bind(UserCreatedByAdminEventContract::class, UserCreatedByAdminEvent::class);
        $this->app->bind(UserLoggedInEventContract::class, UserLoggedInEvent::class);
        $this->app->bind(UserDeletedEventContract::class, UserDeletedEvent::class);
        $this->app->bind(UserUpdatedByAdminEventContract::class, UserUpdatedByAdminEvent::class);
        $this->app->bind(UserUpdatedEventContract::class, UserUpdatedEvent::class);
        $this->app->bind(UserRegisteredBySocialAccountEventContract::class, UserRegisteredBySocialAccountEvent::class);
    }
}

中间件

以下是软件包提供的中间件列表。

附加配置

该软件包包含其他3个软件包,分别是dingo/apitymon/jwt-authprettus/l5-repository

有关这些软件包的其他配置,请参阅它们的文档。

社交媒体登录

配置

配置config/app.php 添加提供者

'providers' => [
   // Other service providers...

   Laravel\Socialite\SocialiteServiceProvider::class,
],

添加别名

'Socialite' => Laravel\Socialite\Facades\Socialite::class,

配置config/services.php

'facebook' => [
    'client_id' => env('FACEBOOK_APP_ID'),
    'client_secret' => env('FACEBOOK_APP_SECRET'),
    'redirect' => env('FACEBOOK_APP_CALLBACK_URL'),
],
'google' => [
    'client_id' => env('GOOGLE_APP_ID'),
    'client_secret' => env('GOOGLE_APP_SECRET'),
    'redirect' => env('GOOGLE_APP_CALLBACK_URL'),
],

配置env

FACEBOOK_CLIENT_ID="App id goes here"
FACEBOOK_CLIENT_SECRET="Secret goes herre"
FACEBOOK_CALLBACK_URL="Url callback"

GOOGLE_CLIENT_ID="App id goes here"
GOOGLE_CLIENT_SECRET="Secret goes herre"
GOOGLE_REDIRECT_URL="Url callback"

在视图中使用

@include('user_component::auth.socialite', 
[ 'iconGg' => '<img src="/assets/images/index/gg.png"alt="Google">', 
  'iconFb' => '<img src="/assets/images/index/fb.png" alt="Facebook">'
])