在接口开发中一般使用传统的Token来验证访问的有效性,但是这种方式非常容易被攻击,当Token被拦截后相当于接口对外开放了,所以需要一种更安全的接口认证方式。
OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版。
下面将介绍如何使用插件 OAuth2.0 服务端 处理你的 API 认证。注意: php版本需要在 7.1 以上。
第一步,下载插件。
第二步,安装扩展库,请确认php版本:# php7.2及以上
composer require league/oauth2-server:8.2建议使用php7.2以上的版本
第三步,创建 private key 和 public key:openssl genrsa -out private.key 2048
openssl rsa -in private.key -pubout > public.keyprivate key 和 public key 放到项目主目录下
第四步,用户模型使用Trait Weasy\Oauth\ApiTokens
用户模型我们使用 fastadmin 的用户模型 app\common\model\User,如下:<?php
namespace app\common\model;
use think\Model;
// 导入 Trait
use Weasy\Oauth\ApiTokens;
/**
* 会员模型
*/
class User extends Model
{
// 使用 ApiTokens Trait
use ApiTokens;
// 开启自动写入时间戳字段
protected $autoWriteTimestamp = 'int';
// 定义时间戳字段名
protected $createTime = 'createtime';
protected $updateTime = 'updatetime';
...
...
}
第五步,创建控制器
在 application/api/controller 下创建控制器 Test.php:<?php
namespace app\api\controller;
use Weasy\Oauth\CheckCredentials;
use app\common\controller\Api;
/**
* 接口
*/
class Test extends Api
{
// 这里使用控制器中间件鉴权
use CheckCredentials;
protected $noNeedLogin = '*';
protected $noNeedRight = '*';
// index 不需要鉴权
protected $noNeedCheck = 'index';
/**
* 初始化,验证 access_token
*/
public function _initialize()
{
parent::_initialize();
// 验证 access_token
$this->handle();
}
public function index()
{
$this->success("你访问的是 index 接口");
}
public function show()
{
$this->success("你访问的是 show 接口");
}
public function delete()
{
$this->success("你访问的是 delete 接口");
}
}
测试
创建密码授权客户端
首先我们进入 http://localhost/addons/oauth/clients 创建一个密码客户端,我用的本地测试,将localhost修改为你的服务器地址,客户端创建如下:
创建完成我们拿到 客户端ID 和 客户端秘钥,也就是OAuth2.0常说的 APP_ID 和 APP_SECRET,有了这两个就可以获取访问令牌了,如下:
获取访问令牌
在访问受保护的API时我们需要获取 access_token 和 refresh_token,URI为oauth/token,我用的本地测试,所以地址是 http://localhost/oauth/token 使用 postman 测试如下:
需要的参数分别是授权类型grant_type,值为 password 密码授权类型
客户端IDclient_id,值为上面获取到的客户端ID
客户端秘钥client_secret,值为上面获取到的客户端秘钥
用户名username,你可以使用fastadmin自带的用户系统创建一个用户
密码password
授权范围scope,如果你需要设定访问范围需加上scope参数
我们拿到访问令牌 access_token 就可以访问受保护的API了。
index 接口
index 方法不用鉴权就可以访问,使用 postman 测试如下:
show接口
在测试show接口或需要用户进行身份验证的任何 API 时,你需要指定两个标头请求头信息。 你必须在 Authorization 请求头中将 token 指定为 Bearer token。 基本上,你必须将收到的 access_token 拼到 Bearer 后面,当中空一个空格。'headers' => [
'Accept' => 'application/json',
'Authorization' => 'Bearer '. $accessToken, // Bearer后面有一个空格
]
使用 postman 测试如下:
不带 Authorization 头:
带 Authorization 头:
可以看到当我们将 access_token 通过 Bearer token 附加到 Authorization 头上后就可以成功访问 show 接口了。
delete接口
delete方法也是受保护的接口,访问时也和 show 接口一样,测试如下:
刷新令牌
如果你拿到的是一个短期授权令牌或访问令牌过期可以使用 refresh_token 刷新令牌来获取新的访问令牌,示例如下:
其中参数将 grant_type 改为 refresh_token,添加参数 refresh_token,值为获取访问令牌时返回的刷新令牌。
注意:刷新令牌refresh_token只能使用一次,上面的方法会重新发出一个刷新令牌。