Laravel Passport 结合 Dingo 实现 API 授权登录登出

准备工作

  • 引入Passport

  • 引入Guzzle

  • 引入Dingo

    composer require laravel/passport
    composer require guzzlehttp/guzzle
    composer require dingo/api
  • 迁移相应的migration文件

    php artisan migrate
  • 安装 Passport

    php artisan passport:install

此处执行结果 初次使用生成的Client ID为1和2

稍后使用的是后者的Client ID和Client Secret

可在项目使用的数据库中oauth_clients数据表查看到对应的id列,secret列

图片


  • 编辑App\User.php 引用HasApiTokens

    可使用Passport提供的辅助方法 用来验证身份和作用域
<?php
namespace App;

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

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;
    // ...
}
  • 注册Passport路由
    编辑App\Providers\AuthServiceProvider.php
<?php
namespace App\Providers;

use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
use Laravel\Passport\Passport;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        'App\Model' => 'App\Policies\ModelPolicy',
    ];

    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();
        Passport::routes();
    }
}
  • 更新auth:api驱动

    编辑config/auth.php
    'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],
    'api' => [
        'driver' => 'passport', // 这里修改为passport
        'provider' => 'users',
    ],
    ],

实现

  • 用户状态控制器App\Http\Controllers\StatusController.php
<?php
namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Http\Requests\LoginRequest;
use Illuminate\Support\Facades\Auth;

use Exception;
use App\Traits\ResponseTrait;
use GuzzleHttp\Client as Guzzle;

class StatusController extends Controller
{
    use ResponseTrait; // 自定义的接口返回Trait 下面贴代码

    private $http;

    public function __construct()
    {
        // 不验证tls
        $this->http = new Guzzle(['verify' => false]); 
    }

    public function login(LoginRequest $request)
    {
        try{
            // .env文件配置APP_URL
            $response = $this->http->post(env('APP_URL').'/oauth/token', [
                'form_params' => [
                    // 使用密码模式
                    'grant_type' => 'password', 
                    'client_id' => '填入你生成的Client ID',
                    'client_secret' => '填入你生成的Secret',
                    'username' => $request->username,
                    'password' => $request->password,
                    'scope' => '*',
                ],
            ]);
        }catch(Exception $e){
            $this->response(1, '登录失败');
        }
        $this->response(0, '登录成功', ['__token' => json_decode((string) $response->getBody(), true)]);
    }

    public function logout()
    {
        if (Auth::check()) {
            Auth::user()->token()->delete();
        }
        $this->response(0, '退出成功');
    }
}
  • App\Http\Requests\LoginRequest.php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class LoginRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'username' => 'required|min:2|max:16',
            'password' => 'required|min:6|max:32'
        ];
    }
}
  • 路由文件 routes/api.php
<?php
$api = app('Dingo\Api\Routing\Router');

$api->version('v1', function ($api) {
    # 登录
    $api->post('login', 'App\Http\Controllers\People\StatusController@login');

    $api->group(['middleware' => ['auth:api'], function ($api) {
        # 退出登录
        $api->get('logout', 'App\Http\Controllers\People\StatusController@logout');
    });
});
  • 接口统一返回Trait
<?php

namespace App\Traits;

trait ResponseTrait
{
    public function response($code, $desc=null, $result=null){
        $arr = [
            'code' => $code,
            'desc' => $desc,
            'result' => $result
        ];
        print json_encode($arr, true);
        exit(0);
    }
}

Postman测试

  • 登录
    登录测试

  • 登出
    登出测试

最后

如果想验证的是别的字段或其他规则

Passport提供了两个方法findForPassportvalidateForPassportPasswordGrant

App\User.php添加




第一次在learnku写作😁 体验很不错

排版可能不是特别严谨

望多多包涵

By LiKachung

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 1

年前过了一年dingo 文档,现在除了这个名字,我什么也不知道了 :sweat:

4年前 评论
lovecn 4年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!