Laravel JWT 多表多用户登录
使用 JWT 方式来实现 API 多用户多表认证
1、先使用 composer
安装 jwt-auth
执行下面命令
composer require "tymon/jwt-auth 1.*@rc"
2、laravel版本大于等于5.5版本可以省略此步骤 注册服务提供者 config/app.php
'providers' => [
Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
]
'aliases' => [
'JWTAuth' => 'Tymon\JWTAuth\Facades\JWTAuth',
'JWTFactory' => 'Tymon\JWTAuth\Facades\JWTFactory',
]
3、发布生成配置文件
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
4、使用以下命令生成密钥
php artisan jwt:secret
5、配置多guard
来区分认证 打开 config/auth.php
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt', // 默认是 token
'provider' => 'users',
],
// 新增admins 模块
'admin' => [
'driver' => 'jwt',
'provider' => 'admins',
]
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Admin::class,
]
],
6、生成相应的数据表 执行下面命令 php artisan make:model Models/Admin -m
生成 model 与对应的表
Schema::create('admins', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
7、执行 php artisan migrate
生成表结构, 执行下面 sql 语句生成数据
# users 表
insert into `users` ( `name`, `email`, `password`, `remember_token`, `created_at`, `updated_at`) values ( 'test123', '994914376@qq.com', '$2y$10$52EQECqdeemEXGoAs9u4iO4gN3CmtC0OY/8snDUEweANw4BQZbiCe', 'z9prihuBKigCGtaEA0GMp6TcyLnFTICUW4F5fuIK6RnZl2o7RC4HQ7BkPOBm', '2019-06-25 03:39:48', '2019-06-25 03:39:48');
# admins 表
insert into `admins` ( `name`, `email`, `password`, `remember_token`, `created_at`, `updated_at`) values ( 'Harvey Jenkins', 'mdouglas@example.com', '$2y$10$DVjo80fNjiPP1qlsW1eRsem9iwXNsClhFgZPQAp47flRUxyk8l/HG', 'XQmmqzC91R', '2019-06-25 05:06:18', '2019-06-25 05:06:18');
8、更改相应的 Model
文件
App\Models\User
<?php
namespace App\Models;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Tymon\JWTAuth\Contracts\JWTSubject;
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',
];
/**
* 获取会储存到 jwt 声明中的标识
* @return mixed
*/
public function getJWTIdentifier()
{
return $this->getKey();
}
/**
* 返回包含要添加到 jwt 声明中的自定义键值对数组
* @return array
*/
public function getJWTCustomClaims()
{
return ['role' => 'user'];
}
}
App\Models\Admin
<?php
namespace App\Models;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Tymon\JWTAuth\Contracts\JWTSubject;
class Admin 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',
];
/**
* 获取会储存到 jwt 声明中的标识
* @return mixed
*/
public function getJWTIdentifier()
{
return $this->getKey();
}
/**
* 返回包含要添加到 jwt 声明中的自定义键值对数组
* @return array
*/
public function getJWTCustomClaims()
{
return ['role' => 'admin'];
}
}
9、在 router/api.php
文件中创建路由信息
# 普通用户登录
Route::group(['prefix' => 'auth'], function () {
Route::post('login', 'AuthController@login');
Route::post('logout', 'AuthController@logout');
Route::post('refresh', 'AuthController@refresh');
Route::post('me', 'AuthController@me')->name('me')->middleware(['jwt.role:user', 'jwt.auth']);
});
# 后台用户登录
Route::group(['prefix' => 'admin', 'namespace' => 'Admin'], function () {
Route::post('login', 'LoginController@login');
Route::post('logout', 'LoginController@logout');
Route::post('refresh', 'LoginController@refresh');
Route::post('me', 'LoginController@me')->middleware(['jwt.role:admin', 'jwt.auth'])->name('me');
});
10、创建相应的控制器
AuthController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\JsonResponse;
class AuthController extends Controller
{
public function __construct()
{
$this->middleware('auth:api', ['except' => ['login']]);
}
/**
* @return JsonResponse
*/
public function login()
{
$credentials = request(['email', 'password']);
if (! $token = auth('api')->attempt($credentials)) {
return response()->json(['error' => 'Unauthorized'], 401);
}
return $this->respondWithToken($token);
}
public function me()
{
return response()->json(auth('api')->user());
}
public function logout()
{
auth('api')->logout();
return response()->json(['message' => 'Successfully logged out']);
}
public function refresh()
{
return $this->respondWithToken(auth('api')->refresh());
}
/**
* @param $token
* @return JsonResponse
*/
protected function respondWithToken($token)
{
return response()->json([
'access_token' => $token,
'token_type' => 'bearer',
'expires_in' => auth('api')->factory()->getTTL() * 60
]);
}
}
Admin/LoginController.php
<?php
namespace App\Http\Controllers\Admin;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
class LoginController extends Controller
{
public function __construct()
{
$this->middleware('auth:admin', ['except' => ['login']]);
}
/**
* @return JsonResponse
*/
public function login()
{
$credentials = request(['email', 'password']);
if (! $token = auth('admin')->attempt($credentials)) {
return response()->json(['error' => 'Unauthorized'], 401);
}
return $this->respondWithToken($token);
}
public function me()
{
return response()->json(auth('admin')->user());
}
public function logout()
{
auth('api')->logout();
return response()->json(['message' => 'Successfully logged out']);
}
public function refresh()
{
return $this->respondWithToken(auth('api')->refresh());
}
/**
* @param $token
* @return JsonResponse
*/
protected function respondWithToken($token)
{
return response()->json([
'access_token' => $token,
'token_type' => 'bearer',
'expires_in' => auth('api')->factory()->getTTL() * 60
]);
}
}
11、创建中间件检测当前 token
对应的是哪个平台 php artisan make:middleware JWTRoleAuth
<?php
namespace App\Http\Middleware;
use Closure;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
class JWTRoleAuth extends BaseMiddleware
{
/**
* JWT 检测当前登录的平台
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param null $role
* @return mixed
*/
public function handle($request, Closure $next, $role = null)
{
try {
// 解析token角色
$tokenRole = $this->auth->parseToken()->getClaim('role');
} catch (JWTException $e) {
/**
* token解析失败,说明请求中没有可用的token。
* 为了可以全局使用(不需要token的请求也可通过),这里让请求继续。
* 因为这个中间件的责职只是校验token里的角色。
*/
return $next($request);
}
// 判断token角色。
if ($tokenRole != $role) {
throw new UnauthorizedHttpException('jwt-auth', 'User role error');
}
return $next($request);
}
}
12、使用 postman
测试接口
13、到此 jwt
多用户 多表认证就已经完成,如有问题和建议可以留言交流
注:以上的一些方式是直接参考网上的部份然后进行整理
本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 5年前 自动加精
好文章
@994914376 楼主,你这里是不是缺少一个步骤:
在 app/Http/Kernel.php 中注册中间件:
博客:Laravel jwt 多表(多用户端)验证隔离
两个帖子,结合着看,豁然开朗。解决了我的疑惑。
这样做就是为了防止串号。
我测试发现,不用写中件间和设置
getJWTCustomClaims
,jwt-auth
这个可以自动区分。jwt-auth
1.0.0-rc.4.1laravel
5.8@十七岁程序员想当歌手
同意。
https://github.com/tymondesigns/jwt-auth/p...
prv 可能在此基础上又加密了一下。
登录正常返回access_token了,然后使用access_token获取用户信息:return response()->json(auth('admin')->user());却报错 "message": "User not found", "status_code": 401,
@raulzhou token是否在header忘记加Bearer + token了
@十七岁程序员想当歌手 我的就是这个版本,中间件用jwt.auth就区分不了,还是走默认
请问在Admin/LoginController.php中,这两个auth方法里面的参数不应该是admin吗
@十七岁程序员想当歌手
遇到诡异的问题,必须要在 user 表里面存在 id 和 admin 表里 id 一样才可以用。。。 目前问题是换成 auth:「$guard」 验证,jwt.role 中间件来过滤
auth('admin')->attempt返回值一直是true,求教如何处理
如果默认的guard里面不存在这个id的话,jwt-auth验证会不通过,返回user not found,有就通过,并且会返回设置的guard里面的数据,请问楼主怎么解决这个的,因为jwt-auth这个中间件一直用默认的guard来判断id在表中是否存在的
laravel7 是不是有bug啊,明明路由里面配置了guard jwt可以解析到但是还是去到users表查询
我的jwt多用户认证的admin没有签发token。。
attempt 返回不是个bool么???
为啥返回异常的时候只是返回 { "message": "Unauthenticated." } 而到不了自定义的异常返回里面,求解