1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace ElfSundae\Laravel\Api\Middleware; |
4
|
|
|
|
5
|
|
|
use Closure; |
6
|
|
|
use ElfSundae\Laravel\Api\Token; |
7
|
|
|
|
8
|
|
|
class VerifyApiToken |
9
|
|
|
{ |
10
|
|
|
/** |
11
|
|
|
* The Token instance. |
12
|
|
|
* |
13
|
|
|
* @var \ElfSundae\Laravel\Api\Token |
14
|
|
|
*/ |
15
|
|
|
protected $token; |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* The URIs that should be excluded from token verification. |
19
|
|
|
* |
20
|
|
|
* @var array |
21
|
|
|
*/ |
22
|
|
|
protected $except = []; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* Create the middleware. |
26
|
|
|
* |
27
|
|
|
* @param \ElfSundae\Laravel\Api\Token $token |
28
|
|
|
*/ |
29
|
|
|
public function __construct(Token $token) |
30
|
|
|
{ |
31
|
|
|
$this->token = $token; |
32
|
|
|
} |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* Handle an incoming request. |
36
|
|
|
* |
37
|
|
|
* @param \Illuminate\Http\Request $request |
38
|
|
|
* @param \Closure $next |
39
|
|
|
* @return mixed |
40
|
|
|
*/ |
41
|
|
|
public function handle($request, Closure $next) |
42
|
|
|
{ |
43
|
|
|
if ($this->inExceptArray($request) || $this->verifyToken($request)) { |
44
|
|
|
$request->attributes->set('current_app_key', $this->getKey($request)); |
45
|
|
|
|
46
|
|
|
return $next($request); |
47
|
|
|
} |
48
|
|
|
|
49
|
|
|
return response('Forbidden Request', 403); |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* Determine if the request has a URI that should be passed through verification. |
54
|
|
|
* |
55
|
|
|
* @param \Illuminate\Http\Request $request |
56
|
|
|
* @return bool |
57
|
|
|
*/ |
58
|
|
|
protected function inExceptArray($request) |
59
|
|
|
{ |
60
|
|
|
foreach ($this->except as $except) { |
61
|
|
|
if ($except !== '/') { |
62
|
|
|
$except = trim($except, '/'); |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
if ($request->is($except)) { |
66
|
|
|
return true; |
67
|
|
|
} |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
return false; |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
/** |
74
|
|
|
* Verify the api token from request. |
75
|
|
|
* |
76
|
|
|
* @param \Illuminate\Http\Request $request |
77
|
|
|
* @return bool |
78
|
|
|
*/ |
79
|
|
|
protected function verifyToken($request) |
80
|
|
|
{ |
81
|
|
|
if ($time = $this->getTime($request)) { |
82
|
|
|
$verifyTime = abs(time() - $time) < (int) config('api.token_duration'); |
83
|
|
|
$verifyToken = $this->token->verify($this->getToken($request), $this->getKey($request), $time); |
|
|
|
|
84
|
|
|
|
85
|
|
|
return $verifyTime && $verifyToken; |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
return false; |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* Get the app key. |
93
|
|
|
* |
94
|
|
|
* @param \Illuminate\Http\Request $request |
95
|
|
|
* @return string |
96
|
|
|
*/ |
97
|
|
|
protected function getKey($request) |
98
|
|
|
{ |
99
|
|
|
return $request->input('_key') ?: $request->header('X-API-KEY'); |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
/** |
103
|
|
|
* Get the time. |
104
|
|
|
* |
105
|
|
|
* @param \Illuminate\Http\Request $request |
106
|
|
|
* @return int |
107
|
|
|
*/ |
108
|
|
|
protected function getTime($request) |
109
|
|
|
{ |
110
|
|
|
return (int) ($request->input('_time') ?: $request->header('X-API-TIME')); |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
/** |
114
|
|
|
* Get the api token. |
115
|
|
|
* |
116
|
|
|
* @param \Illuminate\Http\Request $request |
117
|
|
|
* @return string |
118
|
|
|
*/ |
119
|
|
|
protected function getToken($request) |
120
|
|
|
{ |
121
|
|
|
return $request->input('_token') ?: $request->header('X-API-TOKEN'); |
122
|
|
|
} |
123
|
|
|
} |
124
|
|
|
|
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.