Authenticate.php 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. <?php
  2. /**
  3. * @Name
  4. * @Description
  5. * @Author 刘学玺
  6. * @Date 2023/11/24 16:25
  7. */
  8. namespace App\Http\Middleware\Admin;
  9. use App\Exceptions\ApiException;
  10. use App\Exceptions\Code;
  11. use App\Exceptions\Message;
  12. use Closure;
  13. use Illuminate\Http\Request;
  14. use Illuminate\Support\Facades\Auth;
  15. use Illuminate\Support\Facades\Config;
  16. use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
  17. use Tymon\JWTAuth\Exceptions\JWTException;
  18. use Tymon\JWTAuth\Exceptions\TokenBlacklistedException;
  19. use Tymon\JWTAuth\Exceptions\TokenExpiredException;
  20. use Tymon\JWTAuth\Exceptions\TokenInvalidException;
  21. use Tymon\JWTAuth\Facades\JWTAuth;
  22. class Authenticate
  23. {
  24. public function handle(Request $request, Closure $next)
  25. {
  26. $route_data = $request->route();
  27. $url = str_replace($route_data->getAction()['prefix'] . '/', "", $route_data->uri);
  28. $url_arr = [
  29. 'login',
  30. 'logout'
  31. ];
  32. $api_key = $request->header('apikey');
  33. if ($api_key != config('admin.api_key')) {
  34. throw new ApiException(['code' => Code::TOKEN_ERROR_KEY, 'message' => Message::TOKEN_ERROR_KEY]);
  35. }
  36. if (in_array($url, $url_arr)) {
  37. return $next($request);
  38. }
  39. try {
  40. Config::set('auth.defaults.guard','admin');
  41. if (!JWTAuth::parseToken()->authenticate()) { //获取到用户数据,并赋值给$user 'msg' => '用户不存在'
  42. throw new ApiException(['code' => Code::TOKEN_ERROR_SET, 'message' => Message::TOKEN_ERROR_SET]);
  43. }
  44. } catch (TokenBlacklistedException $e) {
  45. // 这个时候是老的token被拉到黑名单了
  46. throw new ApiException(['code' => Code::TOKEN_ERROR_BLACK, 'message' => Message::TOKEN_ERROR_BLACK]);
  47. } catch (TokenExpiredException $e) {
  48. //token已过期
  49. try {
  50. // 刷新用户的 token
  51. $token = JWTAuth::parseToken()->refresh();
  52. $access_token = 'Bearer '.$token;
  53. $request->headers->set('Authorization',$access_token);
  54. // 使用一次性登录以保证此次请求的成功
  55. Auth::guard('admin')->onceUsingId(JWTAuth::manager()->getPayloadFactory()->buildClaimsCollection()->toPlainArray()['sub']);
  56. $response = $next($request);
  57. $response->headers->set('Access-Control-Expose-Headers',"Authorization");
  58. $response->headers->set('Authorization', $access_token);
  59. return $response;
  60. } catch (JWTException $exception) {
  61. // 如果捕获到此异常,即代表 refresh 也过期了,用户无法刷新令牌,需要重新登录。
  62. throw new ApiException(['code' => Code::TOKEN_ERROR_EXPIRED, 'message' => Message::TOKEN_ERROR_EXPIRED]);
  63. }
  64. // throw new ApiException(['code' => Code::TOKEN_ERROR_EXPIRED, 'message' => Message::TOKEN_ERROR_EXPIRED]);
  65. } catch (TokenInvalidException $e) {
  66. //token无效
  67. throw new ApiException(['code' => Code::TOKEN_ERROR_JWT, 'message' => Message::TOKEN_ERROR_JWT]);
  68. } catch (JWTException $e) {
  69. //'缺少token'
  70. throw new ApiException(['code' => Code::TOKEN_ERROR_JTB, 'message' => Message::TOKEN_ERROR_JTB]);
  71. }
  72. // 写入日志
  73. // (new OperationLogService())->store($user['id']);
  74. return $next($request);
  75. }
  76. }