需求:

新项目,采用前后端分离的模式,前端使用 Vue.js,后端使用 Laravel 5.5构建 Api 服务,用户认证的包使用 jwt-auth 。本次博客会分4步完成,

  1. Laravel 5.5 使用 Jwt-Auth 实现 API 用户认证、刷新令牌(一)。
  2. Laravel–CORS 扩展包完美解决前后端分离应用跨域请求
  3. vue+axios 拦截器实现统一token
  4. Laravel 5.5 使用 Jwt-Auth 实现 API多 用户、多字段认证、刷新令牌(二)

概述:

JWT(JSON Web Token)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。一个JWT实际上就是一个字符串,它由三部分组成,头部、载荷与签名。
更详细讲解地址:https://laravelacademy.org/post/3640.html

安装

1.个人使用laravel5.5 使用composer require tymon/jwt-authphp artisan jwt:generate报错,所以使用以下命令

composer require tymon/jwt-auth:dev-develop --prefer-source

2.安装完成后在配置文件 config/app.php 中注册服务提供者和别名:

'providers' => [Tymon\JWTAuth\Providers\LaravelServiceProvider::class
]'aliases' => ['JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
]

3.发布配置文件

在你项目根目录运行如下命令发布生成config\ jwt.php 的配置文件:

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

4.在发布的配置中生成key:

此命令会在你的 .env 文件中新增一行 JWT_SECRET=secret。

php artisan jwt:secret

5.配置 Auth guard

在 config/auth.php 文件中,你需要将 guards/driver 更新为 jwt:

    'guards' => ['web' => ['driver' => 'session','provider' => 'users',],'api' => ['driver' => 'jwt','provider' => 'users',],],

6.更改 Model
如果需要使用 jwt-auth 作为用户认证,我们需要对我们的 User 模型进行修改,实现一个接口,变更后的 User 模型如下:

<?phpnamespace App;use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;class User extends Authenticatable implements JWTSubject
{use 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',];/*** Get the identifier that will be stored in the subject claim of the JWT.** @return mixed*/public function getJWTIdentifier(){return $this->getKey();}/*** Return a key value array, containing any custom claims to be added to the JWT.** @return array*/public function getJWTCustomClaims(){return [];}}

7.配置项详解

文件位置:config/jwt.php

<?phpreturn [/*|--------------------------------------------------------------------------| JWT Authentication Secret|--------------------------------------------------------------------------|| 用于加密生成 token 的 secret|*/'secret' => env('JWT_SECRET'),/*|--------------------------------------------------------------------------| JWT Authentication Keys|--------------------------------------------------------------------------|| 如果你在 .env 文件中定义了 JWT_SECRET 的随机字符串| 那么 jwt 将会使用 对称算法 来生成 token| 如果你没有定有,那么jwt 将会使用如下配置的公钥和私钥来生成 token|*/'keys' => [/*|--------------------------------------------------------------------------| Public Key|--------------------------------------------------------------------------|| 公钥|*/'public' => env('JWT_PUBLIC_KEY'),/*|--------------------------------------------------------------------------| Private Key|--------------------------------------------------------------------------|| 私钥|*/'private' => env('JWT_PRIVATE_KEY'),/*|--------------------------------------------------------------------------| Passphrase|--------------------------------------------------------------------------|| 私钥的密码。 如果没有设置,可以为 null。|*/'passphrase' => env('JWT_PASSPHRASE'),],/*|--------------------------------------------------------------------------| JWT time to live|--------------------------------------------------------------------------|| 指定 access_token 有效的时间长度(以分钟为单位),默认为1小时,您也可以将其设置为空,以产生永不过期的标记|*/'ttl' => env('JWT_TTL', 60),/*|--------------------------------------------------------------------------| Refresh time to live|--------------------------------------------------------------------------|| 指定 access_token 可刷新的时间长度(以分钟为单位)。默认的时间为 2 周。| 大概意思就是如果用户有一个 access_token,那么他可以带着他的 access_token | 过来领取新的 access_token,直到 2 周的时间后,他便无法继续刷新了,需要重新登录。|*/'refresh_ttl' => env('JWT_REFRESH_TTL', 20160),/*|--------------------------------------------------------------------------| JWT hashing algorithm|--------------------------------------------------------------------------|| 指定将用于对令牌进行签名的散列算法。|*/'algo' => env('JWT_ALGO', 'HS256'),/*|--------------------------------------------------------------------------| Required Claims|--------------------------------------------------------------------------|| 指定必须存在于任何令牌中的声明。| |*/'required_claims' => ['iss','iat','exp','nbf','sub','jti',],/*|--------------------------------------------------------------------------| Persistent Claims|--------------------------------------------------------------------------|| 指定在刷新令牌时要保留的声明密钥。|*/'persistent_claims' => [// 'foo',// 'bar',],/*|--------------------------------------------------------------------------| Blacklist Enabled|--------------------------------------------------------------------------|| 为了使令牌无效,您必须启用黑名单。| 如果您不想或不需要此功能,请将其设置为 false。|*/'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true),/*| -------------------------------------------------------------------------| Blacklist Grace Period| -------------------------------------------------------------------------|| 当多个并发请求使用相同的JWT进行时,| 由于 access_token 的刷新 ,其中一些可能会失败| 以秒为单位设置请求时间以防止并发的请求失败。|*/'blacklist_grace_period' => env('JWT_BLACKLIST_GRACE_PERIOD', 0),/*|--------------------------------------------------------------------------| Providers|--------------------------------------------------------------------------|| 指定整个包中使用的各种提供程序。|*/'providers' => [/*|--------------------------------------------------------------------------| JWT Provider|--------------------------------------------------------------------------|| 指定用于创建和解码令牌的提供程序。|*/'jwt' => Tymon\JWTAuth\Providers\JWT\Namshi::class,/*|--------------------------------------------------------------------------| Authentication Provider|--------------------------------------------------------------------------|| 指定用于对用户进行身份验证的提供程序。|*/'auth' => Tymon\JWTAuth\Providers\Auth\Illuminate::class,/*|--------------------------------------------------------------------------| Storage Provider|--------------------------------------------------------------------------|| 指定用于在黑名单中存储标记的提供程序。|*/'storage' => Tymon\JWTAuth\Providers\Storage\Illuminate::class,],];

8.自定义认证中间件
实现效果:提供账号密码前来登录。如果登录成功,那么我会给前端颁发一个 access _token ,设置在 header 中以请求需要用户认证的路由。
如果用户的令牌如果过期了,可以暂时通过此次请求,并在此次请求中刷新该用户的 access _token,最后在响应头中将新的 access _token 返回给前端,这样子可以无痛的刷新 access _token ,用户可以获得一个很良好的体验,所以开始动手写代码。

执行如下命令以新建一个中间件:

php artisan make:middleware RefreshToken

中间件app\Http\Middleware\RefreshToken.php代码如下:

<?phpnamespace App\Http\Middleware;use Auth;
use Closure;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;// 注意,我们要继承的是 jwt 的 BaseMiddleware
class RefreshToken extends BaseMiddleware
{/*** @param $request* @param Closure $next* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response|mixed* @throws JWTException*/public function handle($request, Closure $next){// 检查此次请求中是否带有 token,如果没有则抛出异常。$this->checkForToken($request);// 使用 try 包裹,以捕捉 token 过期所抛出的 TokenExpiredException  异常try {// 检测用户的登录状态,如果正常则通过if ($this->auth->parseToken()->authenticate()) {return $next($request);}throw new UnauthorizedHttpException('jwt-auth', '未登录');} catch (TokenExpiredException $exception) {// 此处捕获到了 token 过期所抛出的 TokenExpiredException 异常,我们在这里需要做的是刷新该用户的 token 并将它添加到响应头中try {// 刷新用户的 token$token = $this->auth->refresh();// 使用一次性登录以保证此次请求的成功Auth::guard('api')->onceUsingId($this->auth->manager()->getPayloadFactory()->buildClaimsCollection()->toPlainArray()['sub']);} catch (JWTException $exception) {// 如果捕获到此异常,即代表 refresh 也过期了,用户无法刷新令牌,需要重新登录。throw new UnauthorizedHttpException('jwt-auth', $exception->getMessage());}}// 在响应头中返回新的 tokenreturn $this->setAuthenticationHeader($next($request), $token);}
}

然后我们注册一下中间件,文件位置app\Http\Kernel.php在路由处会使用

protected $routeMiddleware = ['refresh' => \App\Http\Middleware\RefreshToken::class,
]

9.更新异常处理的 Handler

由于我们构建的是 api 服务,所以我们需要更新一下 app/Exceptions/Handler.php 中的 render方法,自定义处理一些异常。

<?phpnamespace App\Exceptions;use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;class Handler extends ExceptionHandler
{.../*** Render an exception into an HTTP response.** @param  \Illuminate\Http\Request $request* @param  \Exception $exception* @return \Illuminate\Http\Response*/public function render($request, Exception $exception){// 参数验证错误的异常,我们需要返回 400 的 http code 和一句错误信息if ($exception instanceof ValidationException) {return response(['error' => array_first(array_collapse($exception->errors()))], 400);}// 用户认证的异常,我们需要返回 401 的 http code 和错误信息if ($exception instanceof UnauthorizedHttpException) {return response($exception->getMessage(), 401);}return parent::render($request, $exception);}
}

更新完此方法后,我们上面自定义的中间件里抛出的异常和我们下面参数验证错误抛出的异常都会被转为指定的格式抛出。
10. 路由写法

我们在 routes/api.php 路由文件中新增几条路由来测试一下了:

Route::group(function($router) {$router->post('login', 'AuthController@login');$router->post('logout', 'AuthController@logout');});Route::middleware('refresh')->group(function($router) {$router->get('profile','UserController@profile');
});

11.执行如下命令以新建一个中间件:

php artisan make:controller AuthController

打开此控制器,写入如下内容

<?phpnamespace App\Http\Controllers;use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Transformers\UserTransformer;class AuthController extends Controller
{/*** Get a JWT token via given credentials.** @param  \Illuminate\Http\Request $request** @return \Illuminate\Http\JsonResponse*/public function login(Request $request){// 验证规则,由于业务需求,这里我更改了一下登录的用户名,使用手机号码登录$rules = ['mobile'   => ['required','exists:users',],'password' => 'required|string|min:6|max:20',];// 验证参数,如果验证失败,则会抛出 ValidationException 的异常$params = $this->validate($request, $rules);// 使用 Auth 登录用户,如果登录成功,则返回 201 的 code 和 token,如果登录失败则返回return ($token = Auth::guard('api')->attempt($params))? response(['token' => 'bearer ' . $token], 201): response(['error' => '账号或密码错误'], 400);}/*** 处理用户登出逻辑** @return \Illuminate\Http\JsonResponse*/public function logout(){Auth::guard('api')->logout();return response(['message' => '退出成功']);}
}

好了接下来可以去测试了,我们看一下测试结果

首先感谢原有博主:https://www.jianshu.com/p/9e95a5f8ac4a
本人不才,稍稍抄袭和完善一波,如果博主感觉有问题可以联系本人,感觉这篇文章基本解决我们的Jwt-Auth认证,如此此篇文章对大家有帮助,我愿意以后有时间多多更新,谢谢您的欣赏和参考过的博客

Laravel 5.5 使用 Jwt-Auth 实现 API 用户认证、刷新令牌(一)相关推荐

  1. Laravel 5.5 使用 Jwt-Auth 实现 API 用户认证以及无痛刷新访问令牌

    最近在做一个公司的项目,前端使用 Vue.js,后端使用 Laravel 构建 Api 服务,用户认证的包本来是想用 Laravel Passport 的,但是感觉有点麻烦,于是使用了 jwt-aut ...

  2. php lumen auth,学习 Lumen 用户认证 (一)

    好久没写 PHP 代码了,尤其是 Lumen,我是 Lumen 的忠实用户,自从面世开始,我就将 Lumen 作为我 API 的主要框架使用. 但说到 API,不得不说的一个概念:「前后端分离」,现在 ...

  3. 使用 Jwt-Auth 实现 API 用户认证以及无痛刷新访问令牌

    最近在做一个公司的项目,前端使用 Vue.js,后端使用 Laravel 构建 Api 服务,用户认证的包本来是想用 Laravel Passport 的,但是感觉有点麻烦,于是使用了 jwt-aut ...

  4. SpringtBoot+SpringSecurity+Jwt+MyBatis整合实现用户认证以及权限控制

    文章目录 前言 数据库表结构 项目结构图 核心配置类SecurityConfig 实体类 工具类 用户登录认证 Token令牌验证 获取用户权限 用户权限验证 Service层实现类 统一响应类 Co ...

  5. 基于 JWT + Refresh Token 的用户认证实践

    HTTP 是一个无状态的协议,一次请求结束后,下次在发送服务器就不知道这个请求是谁发来的了(同一个 IP 不代表同一个用户),在 Web 应用中,用户的认证和鉴权是非常重要的一环,实践中有多种可用方案 ...

  6. Laravel 5.5 使用 Jwt-Auth 实现 API多 用户、多字段认证、刷新令牌(二)

    需求 本篇文章继Laravel 5.5 使用 Jwt-Auth 实现 API 用户认证.刷新令牌(一)继续讲解分享 Jwt-Auth实现多表,多字段认证 本次博客会分4步完成,具体可点击查看详情, L ...

  7. Laravel6通过jwt(tymon/jwt-auth)实现API用户无感刷新TOKEN

    Laravel6通过jwt实现API用户无感刷新TOKEN 1.TOKEN是什么 2.jwt是什么 3.jwt安装&配置 3.1.通过composer安装 3.2.发布配置 3.3.生成加密密 ...

  8. Spring Security Oauth2 JWT 实现用户认证授权功能

    Spring Security Oauth2 JWT 一 用户认证授权 1. 需求分析 1.1 用户认证与授权 什么是用户身份认证? 用户身份认证即用户去访问系统资源时系统要求验证用户的身份信息,身份 ...

  9. Rest API的认证模式

    Rest API的认证模式 Rest API的认证模式 AppKey AppKey + Secret JWT OAuth Rest API的认证模式 微服务系统中,很多团队采用了API驱动设计开发,服 ...

最新文章

  1. Java常用类之【日期相关类】
  2. java web乱码_【SpringBoot WEB 系列】RestTemplate 之中文乱码问题 fix
  3. Allegro PCB 如何测量距离?比如走线之间的距离
  4. solr 5.3.1 使用java_Apache Solr 5.3.1 发布下载,Java 全文搜索服务器
  5. 计算机90学时培训小结,90学时培训学习心得体会
  6. 点击头像上传文件的效果
  7. python html模板_Tempy-纯Python语法的HTML模板库
  8. 自学Android到什么程度才能找到工作?
  9. 避免eclipse下启动run就进入debug模式
  10. 数学系之必备参考书+数学系教材推荐
  11. 【矩阵乘法】矩阵求和
  12. 高等数学-空间解析几何与向量代数
  13. MATLAB | 好看的配对箱线图绘制模板
  14. 桌面天气秀 3.6 正式版
  15. 基于Python实现五子棋
  16. python爬虫 批量下载高清大图
  17. 直播课堂系统,打造出超过线下培训场景200%的在线学习课堂
  18. Silvaco TCAD——二维工艺仿真
  19. PS2键盘扫描码:通码与断码
  20. 解决 cnpm : 无法加载文件 C:\Users\hp\AppData\Roaming\npm\cnpm.ps1,因为在此系统上禁止运行脚本。

热门文章

  1. 海思Hi3536开发——处理器整体架构了解
  2. 预测和分类钻孔的毛刺钻孔切削ANN预测
  3. java语言冒泡排序法_Java实现八个常用的排序算法:插入排序、冒泡排序、选择排序、希尔排序等...
  4. vue 点击事件传参写法
  5. linux优化ssd磁盘,Ubuntu系统SSD硬盘优化全记录
  6. 3ds Max 2022操作
  7. 面试官:谈谈你对 Tomcat 调优的看法
  8. Python中hashlib模块详解
  9. 如何在unity3d中实现AR镜头全包裹和AR镜头不包裹效果
  10. 文字转语音v1.0.0纯净版