laravel5.5安装jwt-auth 生成token令牌的示例


Posted in PHP onOctober 24, 2019

1:首先通过composer进行安装

composer require tymon/jwt-auth

laravel5.5安装jwt-auth 生成token令牌的示例

2:添加服务提供者

编辑 config/app.php,在 "providers" 添加:

'Tymon\JWTAuth\Providers\JWTAuthServiceProvider',

laravel5.5安装jwt-auth 生成token令牌的示例

3:添加 Facades

编辑 config/app.php,在 "alias" 添加:

'JWTAuth' => 'Tymon\JWTAuth\Facades\JWTAuth',

'JWTFactory' => 'Tymon\JWTAuth\Facades\JWTFactory',

laravel5.5安装jwt-auth 生成token令牌的示例

4:发布配置文件:

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider"

laravel5.5安装jwt-auth 生成token令牌的示例

5:生成 secret key

: php artisan jwt:generate

安装完成后,执行 php artisan jwt:generate,会报错:

(1).Method Tymon\JWTAuth\Commands\JWTGenerateCommand::handle() does not exist

解决方法,这个需要修改源码:

编辑 vendor/tymon/jwt-auth/src/Commands/JWTGenerateCommand.php,新增:

/**
 * Compatiblity with Laravel >= 5.5
*/
 public function handle()
 {
  $this->fire();
 }

(2)如果未添加服务提供者,直接执行该命令,可能也会报错!

There are no commands defined in the "jwt" namespace

解决方法:

就是上面的添加服务提供者

配置(Configuration)

secret(secret key) - 秘钥

用来签名 token 的秘钥。作者将秘钥与 Laravel 的 APP_KEY 分开,以便开发者可以独立地修改它们。

提供了一个 artisan 命令,为我们生成一个随机秘钥。(php artisan jwt:generate)

ttl(token time to live) - token 生存时间

token 的有效时间,以分钟为单位。建议尽可能设置短点,尤其是当我们也使用 token 刷新机制。

refresh_ttl(refresh time to live) - refresh 生存时间

可以刷新 token 的有效时间,以分钟为单位。例如,如果设置为 2周,那么只能在 2周 内,刷新对应的 token,否则将会抛出 TokenExpiredException 异常。如果超过了刷新的有效时间,必须生成一个全新的 token,这意味着用户需要重新登录。

注:ttl 和 refresh_ttl,用于保持用户的登录状态

algo(hashing algorithm) - hash 算法

用于签名 token 的算法,保留默认值即可

user(user model path) - 用户模型路径

应该指向我们项目的 User 类的命名空间路径

identifier(user identifier) - 用户标识

从 token 的主题声明中,根据什么标识来检索用户(一般是 id)

required_claims(required claims)

这些声明必须存在于 token 的 payload 中,否则将抛出 TokenInvalidException 异常(会检测 token 的 payload 是否存在这些声明)

blacklist_enabled(blacklist enabled)

如果设置为 false,将无法使 token 失效。虽然我们仍然可以刷新令牌,但是之前的令牌仍旧有效,因此这样做非常不安全。但对于非常简单的实现,可能不需要额外的开销(刷新 token 等),我们可以配置它。

providers

jwt-auth 包已经有一些具体实现,可用来实现各种需求。只要遵循相关接口,我们就可以覆盖这些具体实现。

providers.user

指定基于主题声明,来查找用户的实现。

providers.jwt

完成 token 的编码和解码的繁重工作

providers.auth

通过凭证或 id 来认证用户

providers.storage

用于驱动黑名单,并存储 token 直到过期。

创建 tokens(Creating Tokens)

jwt-auth 包为我们提供了创建 token 的多种方法。有简单的方法,如果你想更好的控制,也有更进一步的方法。

开箱即用(out of box),有许多必须的声明,虽然这些都可以配置:

sub(Subject) - 包含 token 的标识符(默认是用户 ID)

iat(Issued At) - token 发布时间(unix 时间戳)

exp(Expiry) - token 过期日期(unix 时间戳)

nbf(Not Before) - 可以使用 token 的最早时间点(unix 时间戳)

iss(Issuer) - token 发布者(默认为请求的 url)

jti(JWT Id) - token 的唯一标识符(sub 和 iat 声明的 md5 值)

aud(Audience) - token 的目标受众(默认不需要)

也允许自定义声明。稍后会介绍。

创建一个基于用户凭证的 token

创建 token 的最常用方法是,通过用户的登录凭证,来认证用户。如果认证成功,则返回一个与该用户相关的 token。例如,假设我们有一个 Laravel AuthenticateController

use JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
 
class AuthenticateController extends Controller
{
 public function authenticate(Request $request)
 {
  // grab credentials from the request
  $credentials = $request->only('email', 'password');
 
  try {
   // attempt to verify the credentials and create a token for the user
   if (! $token = JWTAuth::attempt($credentials)) {
    return response()->json(['error' => 'invalid_credentials'], 401);
   }
  } catch (JWTException $e) {
   // something went wrong whilst attempting to encode the token
   return response()->json(['error' => 'could_not_create_token'], 500);
  }
 
  // all good so return the token
  return response()->json(compact('token'));
 }
}

创建一个基于用户对象的 token

我们可以跳过用户认证,只传递一个用户对象

$user = User::first();
$token = JWTAuth::fromUser($user);

上面的 2 个方法也有第二个参数,可以传递一个 '自定义声明' 的数组

在解码 token 时,这些自定义声明,将和其他声明一起提供。

注意:添加大量的自定义声明,将增加 token 的大小

创建一个基于任意你喜欢的内容的 token

作者给我们提供了对底层类和方法的访问,来提供高级的、可自定义的功能。

示例使用了内建的 'Tymon\JWTAuth\PayloadFactory' 实例(或者使用 JWTFactory 门面):

$customClaims = ['foo' => 'bar', 'baz' => 'bob'];
$payload = JWTFactory::make($customClaims);
$token = JWTAuth::encode($payload);

也可以在 'Tymon\JWTAuth\PayloadFactory' 实例上链式调用声明(或者使用 JWTFactory 门面):

$payload = JWTFactory::sub(123)->aud('foo')->foo(['bar' => 'baz']);
$token = JWTAuth::encode($payload);

认证(Authentication)

一旦用户使用他们的凭证登录,下一步将使用 token 发起一个后续请求,来检索用户详情,以便我们可以将其显示为已登录。

使用内置方法,通过 http 发起认证请求,我们需要设置一个 Authorization 请求头,如下所示:

Authorization: Bearer {yourtokenhere}

Apache 用户需要注意:

Apache 好像会丢弃 Authorization 请求头,如果该请求头不是 base64 编码的 user/pass 组合。为了解决此问题,我们可以在 apache 配置文件中添加一下内容:

RewriteEngine On
  RewriteCond %{HTTP:Authorization} ^(.*)
  RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]

或者,我们可以通过在查询字符串中包含 token 来实现:

http://api.mysite.com/me?token={yourtokenhere}

为了从请求中获取 token,我们可以:

// 会设置 token 到返回的对象中
JWTAuth::parseToken();
// 接着,我们可以继续链式调用方法
$user = JWTAuth::parseToken()->authenticate();

为了获取 token 的值,我们可以调用:

$token = JWTAuth::getToken();

如果设置了一个 token,则会返回 token,否则(为方便起见),它将使用上述方法,尝试从请求中解析 token,如果没有设置 token 或 没有 token 可以被解析,最终返回 false。

当然,如果在我们的程序中有其他入口点,我们也可以根据需要手动设置 token。例如:

JWTAuth::setToken('foo.bar.baz');

从 token 中检索认证过的用户

public function getAuthenticatedUser()
  {
   try {
    if(! $user = JWTAuth::parseToken()->authenticate()){
     return response()->json('user_not_found', 404);
    }
   } catch (Tymon\JWTAuth\Exceptions\TokenExpiredException $e) {
    return response()->json(['token_expired'], $e->getStatusCode());
   } catch (Tymon\JWTAuth\Exceptions\TokenInvalidException $e) {
    return response()->json(['token_invalid'], $e->getStatusCode());
   } catch (Tymon\JWTAuth\Exceptions\JWTException $e) {
    return response()->json(['token_absent'], $e->getStatusCode());
   }
   return response()->json(compact('user'));
  }

如果不喜欢内联捕获多个异常的方法,我们可以随意使用 Laravel 添加全局异常处理程序。

在 app/Exceptions/Handler.php 中,将下面代码添加到 render() 方法:

public function render($request, Exception $e)
  {
   if ($e instanceof Tymon\JWTAuth\Exceptions\TokenExpiredException) {
    return response()->json(['token_expired'], $e->getStatusCode());
   } else if ($e instanceof Tymon\JWTAuth\Exceptions\TokenInvalidException) {
    return response()->json(['token_invalid'], $e->getStatusCode());
   }
 
   return parent::render($request, $e);
  }

中间件和过滤器

如果我们使用的是 Laravel 5,可以使用内置的 2 个中间件:

GetUserFromToken

检查请求头和查询字符串(正如上面解释过的)是否存在 token,并尝试解码 token。如上所述,同样的事件被触发。

RefreshToken

此中间件将再次尝试从请求中解析 token,然后将刷新 token(从而使旧 token 失效),并将其作为下一次响应的一部分返回。这实际上产生了单个使用 token 流,如果 token 被泄露,这种方式会减少攻击,因为它仅对单个请求有效。

为了使用这 2 个中间件,我们需要将它们注册到 app/Http/Kernel.php 里的 $routeMIddleware 属性:

protected $routeMiddleware = [
    ...
    'jwt.auth' => 'Tymon\JWTAuth\Middleware\GetUserFromToken',
    'jwt.refresh' => 'Tymon\JWTAuth\Middleware\RefreshToken',
   ];

以上这篇laravel5.5安装jwt-auth 生成token令牌的示例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
php数组函数序列之array_keys() - 获取数组键名
Oct 30 PHP
在windows服务器开启php的gd库phpinfo中未发现
Jan 13 PHP
PHP 实现explort() 功能的详解
Jun 20 PHP
PHP中echo,print_r与var_dump区别分析
Sep 29 PHP
PHP中使用数组指针函数操作数组示例
Nov 19 PHP
php随机取mysql记录方法小结
Dec 27 PHP
PHP查询快递信息的方法
Mar 07 PHP
Yii快速入门经典教程
Dec 28 PHP
微信红包随机生成算法php版
Jul 21 PHP
自制PHP框架之模型与数据库
May 07 PHP
yii2 commands模式以及配置crontab定时任务的方法
Aug 19 PHP
在laravel中实现事务回滚的方法
Oct 10 PHP
对laravel的csrf 防御机制详解,及form中csrf_token()的存在介绍
Oct 24 #PHP
Laravel (Lumen) 解决JWT-Auth刷新token的问题
Oct 24 #PHP
laravel5.1 ajax post 传值_token示例
Oct 24 #PHP
laravel 5.5 关闭token的3种实现方式
Oct 24 #PHP
Thinkphp 3.2框架使用Redis的方法详解
Oct 24 #PHP
laravel解决迁移文件一次删除创建字段报错的问题
Oct 24 #PHP
PHP Swoole异步读取、写入文件操作示例
Oct 24 #PHP
You might like
基于HBase Thrift接口的一些使用问题及相关注意事项的详解
2013/06/03 PHP
如何在PHP中使用正则表达式进行查找替换
2013/06/13 PHP
PHP用strstr()函数阻止垃圾评论(通过判断a标记)
2013/09/28 PHP
CodeIgniter开发实现支付宝接口调用的方法示例
2016/11/14 PHP
js实现单击图片放大图片的方法
2015/02/17 Javascript
ztree获取选中节点时不能进入可视区域出现BUG如何解决
2015/12/03 Javascript
JavaScript实现点击单元格改变背景色的方法
2016/02/12 Javascript
Markdown与Bootstrap相结合实现图片自适应属性
2016/05/04 Javascript
jQuery+Ajax+PHP弹出层异步登录效果(附源码下载)
2016/05/27 Javascript
js实现点击图片自动提交action的简单方法
2016/10/16 Javascript
vue.js  父向子组件传参的实例代码
2017/10/29 Javascript
node前端模板引擎Jade之标签的基本写法
2018/05/11 Javascript
H5+C3+JS实现五子棋游戏(AI篇)
2020/05/28 Javascript
JS滚轮控制图片缩放大小和拖动的实例代码
2018/11/20 Javascript
微信小程序云开发实现云数据库读写权限
2019/05/17 Javascript
基于JS实现父组件的请求服务过程解析
2019/10/14 Javascript
python实现sublime3的less编译插件示例
2014/04/27 Python
Python设置Socket代理及实现远程摄像头控制的例子
2015/11/13 Python
Python爬虫抓取手机APP的传输数据
2016/01/22 Python
python字典键值对的添加和遍历方法
2016/09/11 Python
在Django同1个页面中的多表单处理详解
2017/01/25 Python
使用python采集脚本之家电子书资源并自动下载到本地的实例脚本
2018/10/23 Python
python 定时器,实现每天凌晨3点执行的方法
2019/02/20 Python
python实现抽奖小程序
2020/04/15 Python
基于Python中isfile函数和isdir函数使用详解
2019/11/29 Python
python模拟实现分发扑克牌
2020/04/22 Python
Python小白不正确的使用类变量实例
2020/05/29 Python
Python 在函数上添加包装器
2020/07/28 Python
html5 canvas fillRect坐标和大小的问题解决方法
2014/03/26 HTML / CSS
军训口号
2014/06/13 职场文书
法学专业求职信
2014/07/15 职场文书
合作协议书范本
2014/10/25 职场文书
2014年化妆品销售工作总结
2014/12/01 职场文书
2015年酒店客房部工作总结
2015/04/25 职场文书
javascript拖曳互换div的位置实现示例
2021/06/28 Javascript
PostgreSQL常用字符串分割函数整理汇总
2022/07/07 PostgreSQL