Laravel Passport OAuth2 API认证 第三方登录
起源:开发的PAI,需要鉴权
API鉴权方式
1:access_key与access_secret的方式
具体实现方式,访问的时候,提供access_key与通过加密算法后的签名(比如md5(access_key access_secret )),其中还可以夹杂时间戳,那访问的时候也要带上时间错,服务端,再用相同的算法,计算一个签名,校对后与访问方提供的签名一致,则鉴权通过。由于access_secret没有参与传输,相对安全,还可以用时间戳校对,设置过期时间。
2:OAuth2 典型代表是第三方登录
相对复杂的一种鉴权方式,Laravel手册 API 认证解决方案:Laravel Passport 部分,有较为详细的实现方式 这里写本文,主要记录Oauth2的实现过程
框架版本Laravel5.8,以下所说手册,也是5.8版本手册
为了更好理解授权过程,建立两个服务器
1:http://localhost:8030 这是laravel授权服务器 (同时是资源服务器) ,这台服务器,安装好Laravel,按照手册,API 认证解决方案:Laravel Passport一文,执行 安装 部分操作 并执行 颁发访问令牌 部分操作。
2:http//localhost 这是实验服务器,需要获取授权服务的授权,然后访问资源服务器的资源。
实现第三方登录 实验服务器上的主要代码
文件/test/pro1/index.php
<?php
$query = http_build_query([
'client_id' => '10',
// 'redirect_uri' => 'http://localhost:8030/auth/callback',
'redirect_uri' => 'http://localhost/test/pro1/callback.php',
'response_type' => 'code',
'scope' => '',
]);
header('location:'.'http://localhost:8030/oauth/authorize?' . $query);
文件 /test/pro1/callback.php
<?php
require __DIR__ . '/vendor/autoload.php';
$http = new GuzzleHttp\Client;
$response = $http->post('http://localhost:8030/oauth/token', [
'form_params' => [
'grant_type' => 'authorization_code',
'client_id' => '10', // your client id
'client_secret' => '9rEg7v9JUGMDBB8mPgnCFurlZEirfVwCat6U3IFp', // your client secret
'redirect_uri' => 'http://localhost/test/pro1/callback.php',
'code' => $_GET['code'],
],
]);
header('Content-type: text/json');
echo $response->getBody();
以上代码的流程图
这种方式实现下来,需要用户登录授权服务器, 并点击授权,才能得到token去访问资源服务器的资源,但是API,如果是纯粹的机器对机器,就不好用了
这里参见手册的 创建一个密码客户端,不过我没实现得了,我的解决方式
使用命令 php artisan passport:client 生成客户端以后,修改表oauth_clients 找到当生成的客户端,然后将password_client字段修改为1,即可访问
文件/test/pro1/password_grant.php
<?php
//实践的时候,使用命令 php artisan passport:client --password 没有成功,原因未找到
//使用命令 php artisan passport:client 生成客户端以后,修改表oauth_clients 找到当生成的客户端,然后将password_client字段修改为1,即可访问
require __DIR__ . '/vendor/autoload.php';
try{
$http = new \GuzzleHttp\Client();
$response = $http->post('http://localhost:8030/oauth/token', [
'form_params' => [
'grant_type' => 'password',
'client_id' => '10',//客户端ID
'client_secret' => '9rEg7v9JUGMDBB8mPgnCFurlZEirfVwCat6U3IFp',//客户端密码
'username' => 'username',//用户可以直接登录的用户名,配置后也可以是邮箱,5.8版本,这个默认是注册后的邮箱
'password' => 'password',//用户名对应的密码
'scope' => '*',
],
]);
header('Content-type: text/json');
echo $response->getBody();
}catch(\Exception $e){
echo $e->getMessage();
}
这样,就不用用户点授权,可以直接打到token了
拿到口令后,就可以去访问服务器资源了
其他实践笔记
鉴权版本要求
composer require laravel/passport "7.*"
报错 1071 Specified key was too long; max key length is 1000 bytes
设置SQL全局引擎 SET GLOBAL default_storage_engine = 'InnoDB';
生成客户端
php artisan passport:client
需要先 执行 php artisan make:auth 与 php artisan migrate 创建基本登录页面
若放到http协议上,感觉access_key与access_secret的方式相对更安全,
若放到https协议上,Oauth2方式较为安全,