一、安装
1.使用composer安装jwt-auth
composer require tymon/jwt-auth
通过该命令安装的可能为 0.5. 版本,执行上述命令后可按照下面所述升级版本:*
在composer.json文件中将tymon/jwt-auth版本修改为1.0.0-rc.1:“tymon/jwt-auth”: “^1.0.0-rc.1”
执行:
composer update
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"
运行后config文件下自动生成jwt.php
4.使用以下命令生成密钥
php artisan jwt:secret
完成后会在.env文件中自动生成密匙
JWT_SECRET=pzBAAzjt1fOhBjKpuuN0OSNhDdeYHnhnLLkWDD68LiDcNIk14CFjDJdjJ1f
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.更改相应的 Model 文件。App\Models\User.php
让User.php实现Tymon\JWTAuth\Contracts\JWTSubject类
实现两个方法:getJWTIdentifier()和getJWTCustomClaims()
<?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'];
}
}
7.在 router/api.php 文件中创建路由信息
# 普通用户登录
Route::group([
'prefix' => 'auth'
], function () {
Route::post('login', [\App\Http\Controllers\AuthController::class,'login']);
Route::post('logout', [\App\Http\Controllers\AuthController::class,'logout']);
Route::post('refresh', [\App\Http\Controllers\AuthController::class,'refresh']);
Route::post('me', [\App\Http\Controllers\AuthController::class,'me'])->name('me')->middleware(['jwt.role:user', 'jwt.auth']);
//如果不走中间件则不用加—>middleware
});
# 后台用户登录
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');
});
8.创建相应的控制器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
]);
}
}
9.(如果需要检查token对应哪个平台)创建中间件检测当前 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);
}
}
并将中间件加入app/Http/Kernel.php
protected $routeMiddleware = [
...
'jwt.role' => JWTRoleAuth::class,
];
10.用postman测试接口
到此 jwt 多用户 多表认证就已经完成