Laravel5.2+Dingo/API+JWTauth的想着问题
来源:互联网 发布:韩国bj 知乎 编辑:程序博客网 时间:2024/05/17 08:43
JWTAuth 默认使用 Users 表做为登录认证的表。而我的需求比较奇葩,共有两个不同的表;除此之外,还需要对 JWTAuth 的错误进行自定义。在搜索无果后,只好自己动手实现这两个需求。
首先解决第二个问题,对 JWTAuth 进行错误自定义。这种情况下,我们可以自己去添加一个中间件处理身份认证。
添加中间件处理身份验证
1、添加一个 Middleware
可以使用命令行添加:
1
php artisan make:middleware GetUserFromToken
此命令将会在 app/Http/Middleware
目录内置立一个名称为 GetUserFromToken
的类。
2、在 GetUserFromToken
中编辑代码,这里仿照 JWTAuth 写了 Middleware
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
namespace App\Http\Middleware;use Closure;use JWTAuth;use Tymon\JWTAuth\Exceptions\JWTException;use Tymon\JWTAuth\Exceptions\TokenExpiredException;use Tymon\JWTAuth\Exceptions\TokenInvalidException;class GetUserFromToken{public function handle($request, Closure $next){$auth = JWTAuth::parseToken();if (! $token = $auth->setRequest($request)->getToken()) {return response()->json(['code' => '','message' => 'token_not_provided','data' => '',]);}try {$user = $auth->authenticate($token);} catch (TokenExpiredException $e) {return response()->json(['code' => '','message' => 'token_expired','data' => '',]);} catch (JWTException $e) {return response()->json(['code' => '','message' => 'token_invalid','data' => '',]);}if (! $user) {return response()->json(['code' => '','message' => 'user_not_found','data' => '',]);}//$this->events->fire('tymon.jwt.valid', $user);return $next($request);}}
我将每次错误返回数据替换成自己设置的错误信息。
3、在 /app/Http/Kernel.php
中 $routeMiddleware
新增如下内容:
1234
protected $routeMiddleware =...'jwt.api.auth' => \App\Http\Middleware\GetUserFromToken::class, //新增注册的中间件;
4、在路由中指定使用 jwt.api.auth
1
['middleware' => 'jwt.api.auth']
完成上面的操作,我们新增处理接口身份认证中间件就完成了。
现在需要处理前一个问题。
多表配置
在 JWTAuth 中,可以在配置文件 jwt.php 中设置 User Model namespace
,所以可以在 Middleware
中 handle
部分添加如下代码来动态配置 User Model namespace
1
config(['jwt.user' => 'App\Models\User']);
这里,我把 User 表放到了 App\Models\
中和其他的统一进行管理。不过我在测试中一直出现 App\User
未定义错误。然后就开始了漫长的定位之旅。首先在访问authenticate
得到
12345678910
public function authenticate($token = false){$id = $this->getPayload($token)->get('sub');if (! $this->auth->byId($id)) {return false;}return $this->auth->user();}
然后,在 Tymon\JWTAuth\Providers\Auth\IlluminateAuthAdapter
中找到 byId
和 user
对应代码如下
123456789
public function byId($id){return $this->auth->onceUsingId($id);}public function user(){return $this->auth->user();}
经过测试发现 auth 实际上是一个 Illuminate\Auth\SessionGuard
实例,然后在其中发现了 onceUsingId
和 user
部分代码
12345678910
public function onceUsingId($id){if (! is_null($user = $this->provider->retrieveById($id))) {$this->setUser($user);return true;}return false;}
在查找 provider
所在位置时定位到文件 Illuminate\Auth\CreatesUserProviders.php
中找到如下代码
123456789101112131415161718
public function createUserProvider($provider){$config = $this->app['config']['auth.providers.'.$provider];if (isset($this->customProviderCreators[$config['driver']])) {return call_user_func($this->customProviderCreators[$config['driver']], $this->app, $config);}switch ($config['driver']) {case 'database':return $this->createDatabaseProvider($config);case 'eloquent':return $this->createEloquentProvider($config);default:throw new InvalidArgumentException("Authentication user provider [{$config['driver']}] is not defined.");}}
这里通过 auth.providers.users
配置设置 $config
,而 auth.providers.users
在文件 auth.php 中默认配置如下
123456
'providers' => ['users' => ['driver' => 'eloquent','model' => App\User::class,],]
所以程序走到了 return $this->createEloquentProvider($config);
这一步,继续跟踪得到:
1234
protected function createEloquentProvider($config){return new EloquentUserProvider($this->app['hash'], $config['model']);}
其中 $config['model']
则就是原型:
12345
public function __construct(HasherContract $hasher, $model){$this->model = $model;$this->hasher = $hasher;}
到此,确定了 model
所在位置,只需要在 Middleware
中添加如下配置
1
config(['auth.providers.users.model' => \App\Models\User::class]);
最终代码如下
1234567891011121314151617181920212223242526272829303132333435363738
config(['jwt.user' => '\App\Models\User']);config(['auth.providers.users.model' => \App\Models\User::class]);$auth = JWTAuth::parseToken();if (! $token = $auth->setRequest($request)->getToken()) {return response()->json(['code' => '','message' => 'token_not_provided','data' => '',]);}try {$user = $auth->authenticate($token);} catch (TokenExpiredException $e) {return response()->json(['code' => '','message' => 'token_expired','data' => '',]);} catch (JWTException $e) {return response()->json(['code' => '','message' => 'token_invalid','data' => '',]);}if (! $user) {return response()->json(['code' => '','message' => 'user_not_found','data' => '',]);}//$this->events->fire('tymon.jwt.valid', $user);return $next($request);
到这里为止,实现了自定义表名功能,在结合自定义 Middleware
部分,就可以实现多表认证。只需要对每一种认证都实现对应的 Middleware
,在接口处分别对不同接口使用不同的 Middleware
进行验证就好。
当然,这样的实现肯定不完美,因为所有的事件部分代码全部删除了。这部分还没有想到什么好的解决办法,自己实现 event 应该是可行的,这里就么有尝试。
转至:http://www.hashcoding.net/2016/04/28/Laravel5-2-Dingo-API-JWTauth-%E7%9A%84%E5%9D%91/
- Laravel5.2+Dingo/API+JWTauth的想着问题
- Lumen 配合使用Dingo/Api的问题。
- Laravel5.3开发API(Dingo+Passport+Swagger)
- 在Laravel5.2中使用dingo+JWT+Swagger
- Laravel5.2简单的API实现
- Laravel5.2简单的API实现
- 关于Dingo API 文档的翻译(1)
- Laravel5.2中出现的问题
- Laravel-dingo/api获取路由
- 转--dingo/api扩展包
- Lumen上使用Dingo/Api做API开发时用JWT-Auth做认证的实现
- Lumen上使用Dingo/Api做API开发时用JWT-Auth做认证的实现
- Lumen上使用Dingo/Api做API开发时用JWT-Auth做认证的实现
- Laravel5.2 关于$errors变量的问题 form 表单验证
- Laravel5.2 Api传递多个变量
- lumen5.4整合dingo/api、jwt-auth
- laravel dingo/api 安装与配置
- laravel 5.4 JWT + Dingo 构建API 攻略
- js 中的关键字罗列
- Spark2.0源码之1_Broadcast
- JS弹出对话框
- LeetCode384. Shuffle an Array
- QT 选中QListView 指定行
- Laravel5.2+Dingo/API+JWTauth的想着问题
- iOS 开发笔记 - 开发中如何实现自动检测更新APP
- Linux Shell 通配符、元字符、转义符使用实例介绍
- TDS 以及 FDS 光谱系统的成像光束
- Access键盘快捷键大全(八)
- wxWidgets 跨平台 GUI 编程
- 什么是常量池
- Python与硬件学习笔记:红外避障红外避障传感器
- 纯css3实现tab切换问题