Composer 安装jwt
$ composer require tymon/jwt-auth 1.0.0-rc.1
将下面这行添加至 config/app.php
文件 providers
数组中:
'providers' => [
Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
]
发布配置文件
在cmd运行
$ php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
此命令会在 config
目录下生成一个 jwt.php
配置文件,你可以在此进行自定义配置。
'ttl' => 60,//这个为token有效时间
在 config/auth.php
文件中,你需要将 guards/driver
更新为 jwt
:
执行如下命令以新建一个中间件:
php artisan make:middleware RefreshToken
代码如下:
<?php
namespace App\Http\Middleware;
use Auth;
use Closure;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
// 注意,我们要继承的是 jwt 的 BaseMiddleware
class RefreshToken extends BaseMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
*
* @throws \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException
*
* @return mixed
*/
public function handle($request, Closure $next)
{
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Methods: *");
header("Access-Control-Allow-Headers: *");
header("Access-Control-Expose-Headers: *");
// 检查此次请求中是否带有 token,如果没有则抛出异常。
$this->checkForToken($request);
// print_r($request->header());
// exit();
// 使用 try 包裹,以捕捉 token 过期所抛出的 TokenExpiredException 异常
try {
// 检测用户的登录状态,如果正常则通过
if ($this->auth->parseToken()->authenticate()) {
// var_dump($this->auth->user());
// exit(0);
return $next($request);
}
throw new UnauthorizedHttpException('jwt-auth', '未登录');
} catch (TokenExpiredException $exception) {
// 此处捕获到了 token 过期所抛出的 TokenExpiredException 异常,我们在这里需要做的是刷新该用户的 token 并将它添加到响应头中
try {
// 刷新用户的 token
$token = $this->auth->refresh();
// 使用一次性登录以保证此次请求的成功
Auth::guard('api')->onceUsingId($this->auth->manager()->getPayloadFactory()->buildClaimsCollection()->toPlainArray()['sub']);
} catch (JWTException $exception) {
// 如果捕获到此异常,即代表 refresh 也过期了,用户无法刷新令牌,需要重新登录。
throw new UnauthorizedHttpException('jwt-auth', $exception->getMessage());
}
}
// 在响应头中返回新的 token
return $this->setAuthenticationHeader($next($request), $token);
}
}
在App\Http\Controllers\AuthController下填写验证规则
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Tymon\JWTAuth\JWTAuth;
class AuthController extends Controller
{
/**
* Get a JWT token via given credentials.
*
* @param \Illuminate\Http\Request $request
*
* @return \Illuminate\Http\JsonResponse
*/
public function login(Request $request)
{
// 验证规则
$rules = [
'username' => [
'required',
'exists:az_user',
],
'password' => 'required',
];
// 验证参数,如果验证失败,则会抛出 ValidationException 的异常
try{
$params = $this->validate($request, $rules);
// var_dump($params);
// exit();
return ($token = Auth::guard('api')->attempt($params))
? response(['token' => 'bearer ' . $token,'code' => 200], 201)
: response(['error' => '账号或密码错误'], 400);
}
catch (\Exception $e){
return response(['data'=>$e->getMessage(),'msg'=>'用户名错误','code' => 200],500);
}
}
/**
* 处理用户登出逻辑
*
* @return \Illuminate\Http\JsonResponse
*/
public function logout()
{
Auth::guard('api')->logout();
return response(['message' => '退出成功']);
}
}
在login进行调用,获取用户token,返回给前端
<?php
namespace App\Http\Controllers\Api\User;
use App\Http\Controllers\Controller;
use App\Http\Model\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use Tymon\JWTAuth\JWTAuth;
class LoginController extends BaseController {
public function login(Request $request)
{
$data= $request->all();
$username=$data['username'];
$password=$data['password'];
$user=new User();
$res=$user->where('username',$username)->first();
if ($res){
if (!Hash::check($password,$res->password)){
return $this->no('','登陆密码不正确');
}
$arr=['id'=>$res['id'],'username'=>$res['username'],'password'=>$password];
$token = Auth::guard('api')->attempt($arr);
return $this->ok('Bearer '.$token);
}else{
return $this->no('','用户不存在');
}
}
public function logout()
{
Auth::guard('api')->logout();
return $this->ok('','退出登陆成功');
}
}
前端接受到token写入Headers传给后端
在路由器添加中间件认证
Route::group(['namespace'=>'Api\index','middleware' => ['token']],function ($router){
$router->get('index','IndexController@index');
});
token验证通过以后即可获取到用户信息
public function index(Request $request){
$res=$request->user();
print_r($res);
}