Laravel5.2+Dingo/API+JWTauth的想着问题
2016-12-06 14:34
781 查看
JWTAuth 默认使用 Users 表做为登录认证的表。而我的需求比较奇葩,共有两个不同的表;除此之外,还需要对 JWTAuth 的错误进行自定义。在搜索无果后,只好自己动手实现这两个需求。
首先解决第二个问题,对 JWTAuth 进行错误自定义。这种情况下,我们可以自己去添加一个中间件处理身份认证。
可以使用命令行添加:
此命令将会在
2、在
我将每次错误返回数据替换成自己设置的错误信息。
3、在
4、在路由中指定使用
完成上面的操作,我们新增处理接口身份认证中间件就完成了。
现在需要处理前一个问题。
这里,我把 User 表放到了
然后,在
经过测试发现 auth 实际上是一个
在查找
这里通过
所以程序走到了
其中
到此,确定了
最终代码如下
到这里为止,实现了自定义表名功能,在结合自定义
当然,这样的实现肯定不完美,因为所有的事件部分代码全部删除了。这部分还没有想到什么好的解决办法,自己实现 event 应该是可行的,这里就么有尝试。
转至:http://www.hashcoding.net/2016/04/28/Laravel5-2-Dingo-API-JWTauth-%E7%9A%84%E5%9D%91/
首先解决第二个问题,对 JWTAuth 进行错误自定义。这种情况下,我们可以自己去添加一个中间件处理身份认证。
添加中间件处理身份验证
1、添加一个 Middleware可以使用命令行添加:
1 | php artisan make:middleware GetUserFromToken |
app/Http/Middleware目录内置立一个名称为
GetUserFromToken的类。
2、在
GetUserFromToken中编辑代码,这里仿照 JWTAuth 写了
Middleware
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152 | <?phpnamespace 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, //新增注册的中间件]; |
jwt.api.auth
1 | ['middleware' => 'jwt.api.auth'] |
现在需要处理前一个问题。
多表配置
在 JWTAuth 中,可以在配置文件 jwt.php 中设置Us e2b8 er Model namespace,所以可以在
Middleware中
handle部分添加如下代码来动态配置
User Model namespace
1 | config(['jwt.user' => 'App\Models\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();} |
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/
相关文章推荐
- Lumen上使用Dingo/Api做API开发时用JWT-Auth做认证的实现
- Laravel (Lumen) 中使用JWT-Auth刷新token的问题
- lumen5.4整合dingo/api、jwt-auth
- laravel 5.4 + dingo api + jwt
- Laravel实现dingo+JWT api接口之配置篇
- How to implement JWT Auth About Restful API in Laravel 5.5
- Laravel实现dingo+JWT api接口之配置篇
- Dingo + Laravel + JWT + Entrust + memcache 实现API设计
- Lumen上使用Dingo/Api做API开发时用JWT-Auth做认证的实现
- Laravel 5 开发API(Dingo Api + JWT)
- Laravel实现dingo+JWT api接口之实战篇
- Lumen上使用Dingo/Api做API开发时用JWT-Auth做认证的实现
- laravel中api验证jwt刷新token的一个问题
- laravel 5.4 + dingo api + jwt 代替Passport
- Laravel 5 中使用 JWT(Json Web Token) 实现基于API的用户认证
- laravel dingo/api 安装与配置
- Laravel-dingo/api获取路由
- Laravel & Lumen RESTFul API 扩展包:Dingo API(二) —— 创建 API Endpoint(路由)
- Laravel & Lumen RESTFul API 扩展包:Dingo API(一) —— 安装配置篇
- Laravel5.2 关于$errors变量的问题 form 表单验证