Better late than never.

laravel 鉴权 laravel-passport 使用

本地 PHP & Laravel 版本

PHP 7.4 
Laravel 6.20

安装

composer required laravel/passport 9.4.0 //根据实际情况选择对应版本即可

生成 laravel passport 使用依赖的数据表

php artisan migrate

执行上面命令会生成如下几张表

image

创建用于生成访问令牌的「个人访问」客户端(本文所讲的)和「密码授权」客户端

php artisan passport:install

执行上面命令会在 oauth_clients 表创建如下数据

ewe

其中 personal_access_client=1 的记录就是我们要用的客户端

完成以上的步骤,接下来就是需要在代码层面去实现了。

关键代码

Model use Laravel\Passport\HasApiTokens Trait

在需要使用 Laravel Passport 的模型中 use HasApiTokens

<?php

namespace App;

use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;
}

配置授权看守器

在配置文件 config/auth.php 中配置需要使用 Laravel Passport 的信息

'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'token',
            'provider' => 'users',
            'hash' => false,
        ],

        'passport-api' => [
            'driver' => 'passport',
            'provider' => 'users',
        ],
    ],

PS:如果这里 provider 不是 users 需要在下面的 providers 数组中添加新的配置指定对应的表

'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\User::class,
        ],
        'new-provider' => [
            'driver' => 'eloquent',
            'model' => App\NewProvider::class, // 指定模型也需要use HasApiTokens 这个 trait
        ],

配置令牌的有效期 & 定义个人访问客户端

要在 AuthServiceProvider 的 boot 方法中调用

/**
 * 注册认证 / 授权服务
 *
 * @return void
 */
public function boot()
{
    $this->registerPolicies();

    // Passport::routes();

    Passport::tokensExpireIn(now()->addDays(15));

    Passport::refreshTokensExpireIn(now()->addDays(30));

    Passport::personalAccessTokensExpireIn(now()->addMonths(6));

    // 指定客户端
    Passport::personalAccessClientId(1);
}

定义中间件

在 app/Http/Middleware 新建 PassportAuthMiddleware 中间件

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class PassportAuthMiddleware
{
    public function handle(Request $request, Closure $next)
    {
        $user = auth("passport-api")->user();
        if ( !$user )
        {
            // 这里可以做抛错处理
        }
        return $next($request);
    }
}

在 app/Http/Kernel.php 中指定刚刚创建的中间件

protected $routeMiddleware = [
        'auth.passport-auth' => PassportAuthMiddleware::class,
    ];

定义路由

Route::post('auth/login', 'AuthController@login');

Route::group([
    'prefix' => 'auth',
    'middleware' => ['auth.passport-auth'],
], function ($router) {
    Route::post('logout', 'AuthController@logout');
    Route::get('me', 'AuthController@me');
    Route::get('refresh', 'AuthController@refresh');
});

定义控制器

<?php

namespace Modules\Api\Http\Controllers\CmsAdmin;

use App\Exceptions\PanicException;
use App\Models\Cms\AdminModel;
use App\Services\Common\ValidatorService;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Laravel\Passport\PersonalAccessTokenResult;

class AuthController extends Controller
{
    /**
     * Create a new AuthController instance.
     *
     *
     * @return void
     */
    public function __construct()
    {
    }

    public function login(Request $request)
    {
        $param = request(['username', 'password']);

        // 
        $user = User::query()->where([
            'username' => $param["username"],
            'password' => md5($param["password"]),
        ])->first();

        if ( !$user )
        {
            // 抛错 账号或密码错误
        }

        $createToken = $user->createToken("cmsAdminLogin");
        return $this->respondWithToken($createToken);
    }

    public function me()
    {
        $admin = auth("passport-api")->user();
        return $admin
    }

    public function logout()
    {
        $user = auth("passport-api")->user();
        $user->token()->revoke();
        return [];
    }

    public function refresh()
    {
        $user = auth("passport-api")->user();
        $user->token()->refresh();
        $createToken = $user->createToken("cmsAdminRefresh");
        return $this->respondWithToken($createToken);
    }

    protected function respondWithToken(PersonalAccessTokenResult $token)
    {
        $access_token = $token->accessToken;
        $token_type = 'bearer';
        $expires_in = (string)$token->token->expires_at;
        return compact('access_token', 'token_type', 'expires_in'));
    }
}

结语

以上就是 laravel passport 使用全过程了。 laravel passport 总体来说跟 jwt-auth 的使用区别不大(这里不考虑非个人访问模式的登录鉴权),个人访问模式此场景多用于前后端分离项目,或者给 app 签发 token 令牌以保证接口访问的安全性。不过 jwt-auth 对 laravel6.0 以上的版本没有很好的支持,所以尝试使用 laravel 官方的扩展包 laravel passport 来完成鉴权,不过鉴于该扩展包实现需要依赖查询 3-4 张表,在有高并发或者多用户访问的情况下,这个包就显得不是那么理想了。

-- END

写的不错,赞助一下主机费

扫一扫,用支付宝赞赏
扫一扫,用微信赞赏
开箱Laravel 6 2020-01-21

暂无评论~~