laravel Passport - 创建 REST API 用户认证以及Dingo/Api v2.0+Passport实现api认证

Posted 左闯

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了laravel Passport - 创建 REST API 用户认证以及Dingo/Api v2.0+Passport实现api认证相关的知识,希望对你有一定的参考价值。

 第一部分:

安装passport

使⽤ Composer 依赖包管理器安装 Passport :

composer require laravel/passport  

接下来,将 Passport 的服务提供者注册到配置⽂件  config/app.php  的providers  数组中:(5.6后不用加 )

Laravel\\Passport\\PassportServiceProvider::class

utf8 的 varchar 类型字符串最长255,换成utf8mb4最长是191,然而框架里面默认长度还是用的 255 导致长度不够了。

所以我们要修改app/Providers/AppServiceProvider.php :
    use Illuminate\\Support\\Facades\\Schema;   
      
    public function boot()  
    {  
        Schema::defaultStringLength(191);  
    }  

在.env 和congfig/database.php文件配置好数据库

然后运行artisan生成数据表:

    php artisan make:auth //必须先运行这个,因为Passport 使用服务提供者注册内部的数据库迁移脚本目录  
    php artisan migrate //再更新  

然后运行 passport:install 命令来创建生成安全访问令牌时用到的加密密钥,同时,这条命令也会创建「私人访问」客户端和「密码授权」客户端:

php artisan passport:install

 

完成上面的步骤,我们可以配置一下Passport。

1. 在Model中,我们需要增加 HasApiTokens class,
2. 在AuthServiceProvider中, 增加 "Passport::routes()", 还可以增加过期时间
3. 在 auth.php中, 更改 api 认证方式为password.

1. app/User.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;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        \'name\', \'email\', \'password\',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        \'password\', \'remember_token\',
    ];
}

 

2. app/Providers/AuthServiceProvider.php

 

namespace App\\Providers;

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

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();
  
        Passport::tokensExpireIn(now()->addDays(30));  //这里设置为30天过期

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

 


} }

 

3. config/auth.php

 

return [
    .....
    .....
    \'guards\' => [
        \'web\' => [
            \'driver\' => \'session\',
            \'provider\' => \'users\',
        ],
        \'api\' => [
            \'driver\' => \'passport\',//这里做了修改
            \'provider\' => \'users\',
        ],
    ],
    .....
    .....
]

 

配置 routes/api.php ,增加相应API路由配置

 

Route::post(\'login\', \'api\\LoginController@login\');  
Route::post(\'register\', \'api\\LoginController@register\');  
  
Route::group([\'middleware\' => \'auth:api\'], function(){  
    Route::post(\'details\', \'api\\LoginController@details\');  
});  

 

创建controller    ---》php artisan make:controller Api/LoginController

代码如下

class LoginController extends Controller
{

    public $successStatus = 200;


    /**
     * login api
     *
     * @return \\Illuminate\\Http\\Response
     */
    public function login(){
        if(Auth::attempt([\'email\' => request(\'email\'), \'password\' => request(\'password\')])){
            $user = Auth::user();
            $success[\'token\'] =  $user->createToken(\'MyApp\')->accessToken;
            return response()->json([\'success\' => $success], $this->successStatus);
        }
        else{
            return response()->json([\'error\'=>\'Unauthorised\'], 401);
        }
    }


    /**
     * Register api
     *
     * @return \\Illuminate\\Http\\Response
     */
    public function register(Request $request)
    {
        $validator =Validator::make($request->all(), [
            \'name\' => \'required\',
            \'email\' => \'required|email\',
            \'password\' => \'required\',
            \'c_password\' => \'required|same:password\',
        ]);


        if ($validator->fails()) {
            return response()->json([\'error\'=>$validator->errors()], 401);
        }


        $input = $request->all();
        $input[\'password\'] = bcrypt($input[\'password\']);
        $user = \\App\\User::create($input);//这里追踪到app/user.php
        $success[\'token\'] =  $user->createToken(\'MyApp\')->accessToken;
        $success[\'name\'] =  $user->name;


        return response()->json([\'success\'=>$success], $this->successStatus);
    }


    /**
     * details api
     *
     * @return \\Illuminate\\Http\\Response
     */
    public function details()
    {
        $user = Auth::user();
        return response()->json([\'success\' => $user], $this->successStatus);
    }

我们测试API使用Postman,在谷歌浏览器插件里可以安装它。

2. Login API

 

3. Get Detailss API

Now,我们来测试API数据获取, 我们需要添加headers在测试Postman中,$accessToken使用Login中的Token即可  格式 Authorization     Bearer空格+token

 

 

 

 

第二部分:Dingo/Api v2.0+Passport实现api认证

1.在composer.json中添加
"require": {
    "dingo/api": "2.0.0-alpha1"
}

2.在控制台中运行

php artisan vendor:publish --provider="Dingo\\Api\\Provider\\LaravelServiceProvider"

在.env文件添加

API_STANDARDS_TREE=vnd  # 公开的及商业项目用 vnd
API_SUBTYPE=api-demo  # 项目简称
API_PREFIX=api  # 前缀
API_VERSION=v1  # 不提供版本时使用的版本号
API_NAME="Laravel Api Demo"  # 使用 API Blueprint 命令生成文档的时候才用到
API_STRICT=false # Strict 模式要求客户端发送 Accept 头而不是默认在配置文件中指定的版本,这意味着你不能通过Web浏览器浏览API
API_DEFAULT_FORMAT=json
API_DEBUG=false # 开启 debug 模式

 

 

打开 config/app.php,注册必要的 service provider 在你的应用 providers 之前 5.6后可以不加

    \'providers\' => [  
        Dingo\\Api\\Provider\\LaravelServiceProvider::class  
    ]  

再次设置更改路由,

打开 routes/api.php 文件添加

$api = app(\'Dingo\\Api\\Routing\\Router\');
$api->version(\'v1\',function ($api) {
    $api->post(\'login\', \'App\\Http\\Controllers\\Api\\LoginController@login\');
    $api->post(\'register\', \'App\\Http\\Controllers\\Api\\LoginController@register\');
    $api->group([\'middleware\' => \'auth:api\'], function($api){
        $api->post(\'details\', \'App\\Http\\Controllers\\Api\\LoginController@details\');
    });
});

 

这里我们可以用刚才生成的Client ID与Client Secret来密码认证访问,注册,登录 与详情页面,都能正常访问。(这几个页面的访问不变,程序代码不变)。


1.使用其他的数据表 例如test_user 只需在app/user.php中添加protected $table = \'test_user\';
2.你可以自己定义你想要的登录验证字段
if(Auth::attempt([\'id\' => request(\'id\'), \'password\' => request(\'password\')])){//这里修改为了id和密码
            $user = Auth::user();
            $success[\'token\'] =  $user->createToken(\'MyApp\')->accessToken;
            return response()->json([\'success\' => $success], $this->successStatus);
        }
        else{
            return response()->json([\'error\'=>\'Unauthorised\'], 401);
        }

 当然你也可以把app/user.php移动到app/Models下面  所有的数据模型文件,都 必须 存放在:app/Models/ 文件夹中。这样更合理

然后修改

  1. 修改User.php的namespace为App\\Models
  2. 执行composer dumpautoload,重新加载类
  3. config/auth.php文件中的providers部分的model对应的类,修改为App\\Models\\User::
 

 

 
 
 

以上是关于laravel Passport - 创建 REST API 用户认证以及Dingo/Api v2.0+Passport实现api认证的主要内容,如果未能解决你的问题,请参考以下文章

php Laravel Passport登录用户并创建令牌

Laravel Passport 没有身份验证

无法找到 [Laravel\Passport\Client] 的工厂

401 未经授权使用带有 Laravel Passport 的不记名令牌

Laravel 6 Passport CSRF 令牌不匹配

Laravel Passport API:检索经过身份验证的令牌