Skip to content

Commit 0df81a5

Browse files
authored
Merge pull request #4 from BinarCode/dev-sanctum
dev sanctum
2 parents 6012827 + b10e458 commit 0df81a5

File tree

5 files changed

+165
-0
lines changed

5 files changed

+165
-0
lines changed

README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,41 @@ $timing->stopAllUnfinishedEvents();
218218
$timing->getDuration();
219219
```
220220

221+
222+
## Sanctum dev auth
223+
224+
Each `api` has authentication, and testing it via HTTP Client (ie postman) we spend a lot of time to login users and copy the token, put in the next request and so on. Well now Laravel Developer provides an easy way to authenticate users in `local` env using `testing` token:
225+
226+
```php
227+
// app/Http/Kernel.php
228+
229+
'api' => [
230+
//...
231+
\Binarcode\LaravelDeveloper\Middleware\DevSanctumAuthMiddleware::class,
232+
]
233+
```
234+
235+
And send the request with the `Authorization` header value `testing`.
236+
237+
Note: Make sure the `DevSanctumAuthMiddleware` is placed before the `api` middleware.
238+
239+
### Customize resolved user
240+
241+
By default, the first entry (usually user) from your config model `app.providers.users.model` will be used, however, you can customize that.
242+
243+
In any of yours service providers, or in the same place you inject the `DevSanctumAuthMiddleware` you can provide a callback which resolves the user instance:
244+
245+
```php
246+
use App\Models\User;
247+
use Binarcode\LaravelDeveloper\Middleware\DevSanctumAuthMiddleware;
248+
249+
'middleware' => [
250+
DevSanctumAuthMiddleware::resolveUserUsing(function() {
251+
return User::first();
252+
});
253+
'api',
254+
],
255+
```
221256
## Testing
222257

223258
``` bash

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"laravel/slack-notification-channel": "^2.3"
2323
},
2424
"require-dev": {
25+
"laravel/sanctum": "^2.8",
2526
"orchestra/testbench": "^6.0",
2627
"phpunit/phpunit": "^9.3",
2728
"symfony/stopwatch": "^4.4|^5.0",
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
namespace Binarcode\LaravelDeveloper\Middleware;
4+
5+
use Closure;
6+
use Illuminate\Http\Request;
7+
use Illuminate\Support\Facades\App;
8+
9+
class DevSanctumAuthMiddleware
10+
{
11+
/**
12+
* @var Closure
13+
*/
14+
public static $resolveUser;
15+
16+
/**
17+
* Handle an incoming request.
18+
*
19+
* @param \Illuminate\Http\Request $request
20+
* @param \Closure $next
21+
* @return mixed
22+
*/
23+
public function handle(Request $request, Closure $next)
24+
{
25+
if (! App::environment('local')) {
26+
return $next($request);
27+
}
28+
29+
if ($request->header('Authorization') !== 'Bearer testing') {
30+
return $next($request);
31+
}
32+
33+
if (is_callable(static::$resolveUser)) {
34+
$user = call_user_func(static::$resolveUser, $request);
35+
} else {
36+
/** * @var string $class */
37+
$class = config('app.providers.users.model');
38+
39+
$user = $class::query()->first();
40+
}
41+
42+
43+
if (is_null($user)) {
44+
return $next($request);
45+
}
46+
47+
if (! in_array(\Laravel\Sanctum\HasApiTokens::class, class_uses_recursive($user))) {
48+
return $next($request);
49+
}
50+
51+
$token = $user->createToken('login')->plainTextToken;
52+
53+
$bag = $request->headers;
54+
55+
$bag->add([
56+
'Authorization' => "Bearer {$token}",
57+
]);
58+
59+
return $next($request);
60+
}
61+
62+
public static function resolveUserUsing(Closure $resolveUser): string
63+
{
64+
static::$resolveUser = $resolveUser;
65+
66+
return static::class;
67+
}
68+
}

tests/Fixtures/User.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace Binarcode\LaravelDeveloper\Tests\Fixtures;
4+
5+
use Laravel\Sanctum\PersonalAccessToken;
6+
7+
class User
8+
{
9+
use \Laravel\Sanctum\HasApiTokens;
10+
11+
public function createToken(string $name, array $abilities = ['*'])
12+
{
13+
return tap(new PersonalAccessToken(), function (PersonalAccessToken $token) {
14+
$token->plainTextToken = 'foo';
15+
});
16+
}
17+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
namespace Binarcode\LaravelDeveloper\Tests\Middleware;
4+
5+
use Binarcode\LaravelDeveloper\Middleware\DevSanctumAuthMiddleware;
6+
use Binarcode\LaravelDeveloper\Tests\Fixtures\User;
7+
use Binarcode\LaravelDeveloper\Tests\TestCase;
8+
use Illuminate\Http\Request;
9+
use Illuminate\Support\Facades\App;
10+
use Symfony\Component\HttpFoundation\HeaderBag;
11+
12+
class DevSanctumAuthMiddlewareTest extends TestCase
13+
{
14+
public function test_can_authenticate_using_testing()
15+
{
16+
DevSanctumAuthMiddleware::resolveUserUsing(function () {
17+
return new User();
18+
});
19+
20+
$middleware = new DevSanctumAuthMiddleware();
21+
22+
$request = tap(new Request(), function (Request $request) {
23+
/** * @var HeaderBag $bag */
24+
$bag = $request->headers;
25+
26+
$bag->add([
27+
'Authorization' => "Bearer testing",
28+
]);
29+
});
30+
31+
$next = function ($request) {
32+
return $request;
33+
};
34+
35+
App::partialMock()
36+
->expects('environment')
37+
->andReturnTrue();
38+
39+
$middleware->handle($request, $next);
40+
41+
$this->assertTrue($request->hasHeader('Authorization'));
42+
$this->assertSame($request->header('Authorization'), 'Bearer foo');
43+
}
44+
}

0 commit comments

Comments
 (0)