基于 JWT-Auth 实现 API 验证
基于 JWT-Auth 实现 API 验证
如果想要了解其生成Token的算法原理,请自行查阅相关资料
需要提及的几点:
使用session存在的问题:
session和cookie是为了解决http无状态的方案。session是用户保存在服务器中的状态信息,cookie中则保存jsessionId,请求服务器时,服务器读取jsessionId从而确定用户的身份信息,而session+cookie用在restful接口上破坏了其“无状态”的特性,session运行时都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大。这也是restful最致力于通过“无状态”解决的问题。如果使用session,那么restful也就没有什么意义了
session降低了系统扩展性。用户认证之后,服务端做认证记录,如果认证的记录被保存在内存中的话,这意味着用户下次请求还必须要请求在这台服务器上,这样才能拿到授权的资源,这样在分布式的应用上,相应的限制了负载均衡器的能力。这也意味着限制了应用的扩展能力
cookie不安全,很容易导致跨站请求伪造攻击(CSRF)
token存在的问题:
如,如何确定token的过期时间?如果token的有效期过短,很容易造成用户用着用着就掉线的情况,降低用户体验。但目前看来好像并没有太好的办法,只能尽量延长token的有效期,或者每隔一次前端自动向服务端请求一次token
基于 JWT-Auth 的 token 验证体系
(亲测,希望这篇文章让大家少入坑)
运行软件版本
laravel 5.5
安装 JWT-Auth 扩展包
composer require tymon/jwt-auth "1.5.*"安装完后在配置文件
config/app.php中添加注册服务提供者和别名:...
'providers' => [
...
Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class,
]
...
'aliases' => [
...
'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
]发布资源配置
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider"
运行以下命令生成密钥
key在生成的config/jwt.php中// 如果运行后报错,提示ERROR:Method Tymon\JWTAuth\Commands\JWTGenerateCommand::handle() does not exist,将vendor\tymon\jwt-auth\src\Commands\JWTGenerateCommand.php文件中的 fire() 方法修改为 handle()即可正常生成秘钥
php artisan jwt:generate编辑
app/Http/Kernel.php添加jwt.auth和jwt.refresh到应用路由中间件数组:protected $routeMiddleware = [
...
'jwt.auth' => \Tymon\JWTAuth\Middleware\GetUserFromToken::class,
// 'jwt.refresh' => \Tymon\JWTAuth\Middleware\RefreshToken::class,
];JWTAuth自身中间件\Tymon\JWTAuth\Middleware\GetUserFromToken中包含了对生成token的各类情况的验证,以及异常的抛出。下面是其底层验证类GetUserFromToken::class:// file_path : vendor\tymon\jwt-auth\src\Middleware\GetUserFromToken.php
<?php
/*
* This file is part of jwt-auth.
*
* (c) Sean Tymon <tymon148@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Tymon\JWTAuth\Middleware;
use Tymon\JWTAuth\Exceptions\JWTException; //验证异常类
use Tymon\JWTAuth\Exceptions\TokenExpiredException;//token过期异常验证类
class GetUserFromToken extends BaseMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, \Closure $next)
{
if (! $token = $this->auth->setRequest($request)->getToken()) {
return $this->respond('tymon.jwt.absent', 'token_not_provided', 400);
}
try {
$user = $this->auth->authenticate($token);
} catch (TokenExpiredException $e) {
return $this->respond('tymon.jwt.expired', 'token_expired', $e->getStatusCode(), [$e]);
} catch (JWTException $e) {
return $this->respond('tymon.jwt.invalid', 'token_invalid', $e->getStatusCode(), [$e]);
}
if (! $user) {
return $this->respond('tymon.jwt.user_not_found', 'user_not_found', 404);
}
$this->events->fire('tymon.jwt.valid', $user);
return $next($request);
}
}其中,调用的
respond的方法在vendor\tymon\jwt-auth\src\Middleware\BaseMiddleware.php文件中/**
* Fire event and return the response.
*
* @param string $event
* @param string $error
* @param int $status
* @param array $payload
* @return mixed
*/
protected function respond($event, $error, $status, $payload = [])
{
$response = $this->events->fire($event, $payload, true);
return $response ?: $this->response->json(['error' => $error], $status);
}可看到,当出现异常需要返回错误信息时,会连带返回一个
fire event的警告事件对象,这里不做详述。由底层代码中,可以了解到,我们如果想自定义自己所需要的验证方法,可以将这
GetUserFromToken::class内容复制到我们自己自定义的中间件中。比如:创建自定义的验证中间件
App\Http\Middleware\JwtAuth.phpphp artisan make:middleware JwtAuth
全部复制到自定义的中间件中后,校验下中间件中需要的类是否应用完全,命名空间是否正确等等,检查无误后根据需要自行定义需要的验证功能。
// demo
namespace App\Http\Middleware;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Closure;
use Tymon\JWTAuth\Middleware\BaseMiddleware;
class JwtAuth extends BaseMiddleware
{
public function handle($request, \Closure $next)
{
if (! $token = $this->auth->setRequest($request)->getToken()) {
return $this->respond('tymon.jwt.absent', 'token_not_provided', 400);
}
try {
$user = $this->auth->authenticate($token);
} catch (TokenExpiredException $e) {
return $this->respond('tymon.jwt.expired', 'token_expired', $e->getStatusCode(), [$e]);
} catch (JWTException $e) {
return $this->respond('tymon.jwt.invalid', 'token_invalid', $e->getStatusCode(), [$e]);
}
if (! $user) {
return $this->respond('tymon.jwt.user_not_found', 'user_not_found', 404);
}
$this->events->fire('tymon.jwt.valid', $user);
return $next($request);
}
}定义完成后将自定义的中间件放入
app\Http\Kernel.php的中间件数组中。protected $routeMiddleware = [
...
//'jwt.auth' => \Tymon\JWTAuth\Middleware\GetUserFromToken::class,
'jwt.auth_self' => \App\Http\Middleware\JwtAuth::class
];添加好后,即可在
routes/api.php中对需要控制的api路由进行验证控制Route::group(['middleware'=>'jwt.auth_self'],function(){
// 需要控制的api路由
// ... code
});
我们现在可以对请求来的路由进行token的验证,那么接下来我们就需要生成这个token,让后续访问中间件中的请求路由都携带这个token就能实现验证。这里要提一下在安装
JWT-Auth过程中生成的配置文件config/jwt.php<?php
return [
...
/*
|--------------------------------------------------------------------------
| User Model namespace
|--------------------------------------------------------------------------
|
| Specify the full namespace to your User model.
| e.g. 'Acme\Entities\User'
|
*/
// 设置你的用户model,默认为laravel自带的 User model
'user' => 'App\User',
]如果需求需要,可在配置文件中修改用户
mode,但配置的model中需要引用Illuminate\Foundation\Auth\User as Authenticatable,并继承,写法和User model一致具体的请求登录以及获取token信息,登出等功能实现,可参考此文章
Laravel 5 中使用 JWT(Json Web Token) 实现基于API的用户认证,这里简单提及下常用到的有关其token的方法
<?php
namespace App\Http\Controller; use Tymon\JWTAuth\JWTAuth; class Auth{
public function test (JWTAuth $JWTAuth){
// 获取请求携带中的token
$token = $JWTAuth -> getToken();
// 获取token中的用户信息
$user = $JWTAuth -> parseToken() -> authenticate();
// 销毁此次生成的token
$JWTAuth->setToken( $JWTAuth->getToken() )->invalidate();
// 自定义生成token,如果需要
$JWTAuth->setToken('foo.bar.baz');
}
}
基于 JWT-Auth 实现 API 验证的更多相关文章
- ASP.NET Core WebApi基于JWT实现接口授权验证
一.ASP.Net Core WebApi JWT课程前言 我们知道,http协议本身是一种无状态的协议,而这就意味着如果用户向我们的应用提供了用户名和密码来进行用户认证,那么下一次请求时,用户还要再 ...
- 基于JWT的Token身份验证
身份验证,是指通过一定的手段,完成对用户身份的确认.为了及时的识别发送请求的用户身份,我们调研了常见的几种认证方式,cookie.session和token. 1.Cookie cookie是 ...
- 基于JWT的web api身份验证及跨域调用实践
随着多终端的出现,越来越多的站点通过web api restful的形式对外提供服务,很多网站也采用了前后端分离模式进行开发,因而在身份验证的方式上可能与传统的基于cookie的Session Id的 ...
- 前端和后端采用接口访问时的调用验证机制(基于JWT的前后端验证)(思路探讨)
说明:基于前后端,尤其是使用Ajax请求的接口,现在市面上网页上调用的Ajax基本都是没有验证的,如果单独提取之后可以无线的刷数据. 继上一篇http://www.cnblogs.com/EasonJ ...
- asp.net core 2.0 web api基于JWT自定义策略授权
JWT(json web token)是一种基于json的身份验证机制,流程如下: 通过登录,来获取Token,再在之后每次请求的Header中追加Authorization为Token的凭据,服务端 ...
- ASP.NET Web API 2系列(四):基于JWT的token身份认证方案
1.引言 通过前边的系列教程,我们可以掌握WebAPI的初步运用,但是此时的API接口任何人都可以访问,这显然不是我们想要的,这时就需要控制对它的访问,也就是WebAPI的权限验证.验证方式非常多,本 ...
- 基于jwt的token验证
一.什么是JWT Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519). 该token被设计为紧凑且安全的,特别适用于分布 ...
- 基于Volley,Gson封装支持JWT无状态安全验证和数据防篡改的GsonRequest网络请求类
这段时间做新的Android项目的client和和REST API通讯框架架构设计.使用了非常多新技术,终于的方案也相当简洁优雅.client仅仅须要传Java对象,server端返回json字符串, ...
- 在ASP.NET Web API 2中使用Owin基于Token令牌的身份验证
基于令牌的身份验证 基于令牌的身份验证主要区别于以前常用的常用的基于cookie的身份验证,基于cookie的身份验证在B/S架构中使用比较多,但是在Web Api中因其特殊性,基于cookie的身份 ...
随机推荐
- nginx负载均衡之入门配置
先来简单了解一下什么是负载均衡,单从字面上的意思来理解就可以解释N台服务器平均分担负载,不会因为某台服务器负载高宕机而某台服务器闲置的情况.那么负载均衡的前提就是要有多台服务器才能实现,也就是两台以上 ...
- 题目1005:Graduate Admission(结构体排序)
问题来源 http://ac.jobdu.com/problem.php?pid=1005 问题描述 这道题理解题意有些麻烦,多看几遍先理解题意再说.每个学生有自己的三个成绩,一个编号,以及一个志愿列 ...
- ubuntu 14.04网卡配置以及关闭防火墙
一.Ubuntu网卡配置如下: 在文件/etc/network/interfaces中进行以下配置 auto lo iface lo inet lookback auto eth0 iface eth ...
- request.getSession(true/false)的区别
javax.servlet.http.HttpServletRequest接口有两个方法:getSession(boolean)和getSession(). 具体什么区别,跟踪源码分析下,先摆出结论: ...
- FJWC2019 直径
题目描述 你需要构造一棵至少有两个顶点的树,树上的每条边有一个非负整数边权.树上两点 i,j 的距离dis(i,j) 定义为树上连接i 和j 这两点的简单路径上的边权和. 我们定义这棵树的直径为,所有 ...
- bzoj4998: 星球联盟(link-cut-tree)
题面 bzoj 题解 bzoj2959: 长跑的弱化版 产生了环就并查集维护一下 Code #include<bits/stdc++.h> #define LL long long #de ...
- 开源.net 混淆器ConfuserEx介绍 [转]
今天给大家介绍一个开源.net混淆器——ConfuserEx http://yck1509.github.io/ConfuserEx/ 由于项目中要用到.net 混淆器,网上搜寻了很多款,比如Dotf ...
- c#Filestream类(文件流)
0.创建文件流几种方法: File.Open("a.txt",FileMode.Create,FileAccess.ReadWrite); File.OpenWrite(" ...
- Ubuntu 安装ftp
Ubuntu 用vsftpd 配置FTP服务器 网上的文章好难懂啊..只想要简单粗暴,弄好能用就行啊,复杂的以后研究不行吗...折腾好久,其实弄出来能用不就这么点内容吗... 本文在Ubuntu Se ...
- C++中的名字重整技术
C++ 一直为人诟病之一的原因是他的二进制模块兼容性不好,即ABI(Application Binary Interface)问题.对于同一源代码,不同编译器,甚至同一编译器不同版本都不兼容,其编译出 ...