jsdecena / laravel-passport-multiauth
简单的 Laravel Passport 多用户认证
v0.2.4
2017-10-14 23:51 UTC
Requires
- illuminate/http: ^5.3
- laravel/framework: 5.5.*
- vlucas/phpdotenv: ~2.2
Requires (Dev)
- fzaninotto/faker: ~1.4
- mockery/mockery: 0.9.*
- phpunit/phpunit: ~4.0
This package is auto-updated.
Last update: 2024-09-09 15:33:05 UTC
README
Laravel passport 默认行为是在 users
表上对 user
进行认证。
虽然这对大多数应用来说已经足够好,但有时如果出现新的需求,我们可能需要对其进行一点调整。
我创建了这个中间件,因为我需要一些用户组可以访问应用,并且每个用户组都有角色。
如何安装
- 在您的终端中运行
composer require jsdecena/laravel-passport-multiauth
或将其添加到您的composer.json
"require": {
...
"jsdecena/laravel-passport-multiauth": "^0.2",
...
},
- 在您的
config/app.php
中添加此行
'providers' => [
...
Jsdecena\LPM\LaravelPassportMultiAuthServiceProvider::class,
...
]
- 在您的
app\Http\Kernel.php
中添加此行
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
protected $routeMiddleware = [
...
'mmda' => \Jsdecena\LPM\Middleware\ProviderDetectorMiddleware::class,
];
- 同样在您的
routes/api.php
中
Route::post('oauth/token/', 'CustomerTokenAuthController@issueToken')
->middleware(['mmda', 'throttle'])
->name('issue.token');
趣闻:为什么是 mmda?因为在菲律宾,他们是处理交通的人 😅
- 并在
config/auth.php
中
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
'customers' => [
'driver' => 'passport',
'provider' => 'customers'
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => 'App\User',
],
/**
* This is the important part. You can create as many providers as you like but right now,
* we just need the customer
*/
'customers' => [
'driver' => 'eloquent',
'model' => 'App\Customer',
],
],
在您的控制器中,您可以通过
auth()->guard('customer')->user()
访问已登录的用户
- 您的
Customer
模型应该扩展Authenticatable
并使用Notifiable
和HasApiTokens
特性
<?php
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens;
class Customer extends Authenticatable
{
use Notifiable, HasApiTokens;
/**
* 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',
];
}
请注意,您需要
Customer
模型或您需要认证的任何模型。
-
迁移客户表
php artisan vendor:publish --tag=migrations
-
并在您的控制器中:
App\Http\Controllers\Auth\CustomerTokenAuthController.php
<?php
namespace App\Http\Controllers\Auth;
use App\Customers\Customer;
use App\Customers\Exceptions\CustomerNotFoundException;
use Illuminate\Database\ModelNotFoundException;
use Laravel\Passport\Http\Controllers\AccessTokenController;
use Laravel\Passport\TokenRepository;
use League\OAuth2\Server\AuthorizationServer;
use Psr\Http\Message\ServerRequestInterface;
use Lcobucci\JWT\Parser as JwtParser;
class CustomerTokenAuthController extends AccessTokenController
{
/**
* The authorization server.
*
* @var \League\OAuth2\Server\AuthorizationServer
*/
protected $server;
/**
* The token repository instance.
*
* @var \Laravel\Passport\TokenRepository
*/
protected $tokens;
/**
* The JWT parser instance.
*
* @var \Lcobucci\JWT\Parser
*/
protected $jwt;
/**
* Create a new controller instance.
*
* @param \League\OAuth2\Server\AuthorizationServer $server
* @param \Laravel\Passport\TokenRepository $tokens
* @param \Lcobucci\JWT\Parser $jwt
*/
public function __construct(AuthorizationServer $server,
TokenRepository $tokens,
JwtParser $jwt)
{
parent::__construct($server, $tokens, $jwt);
}
/**
* Override the default Laravel Passport token generation
*
* @param ServerRequestInterface $request
* @return array
* @throws UserNotFoundException
*/
public function issueToken(ServerRequestInterface $request)
{
$body = (parent::issueToken($request));
$token = json_decode($body, true);
if (array_key_exists('error', $token)) {
return response()->json([
'error' => $token['error'],
'status_code' => 401
], 401);
}
$data = $request->getParsedBody();
$email = $data['username'];
switch ($data['provider']) {
case 'customers';
try {
$user = Customer::where('email', $email)->firstOrFail();
} catch (ModelNotFoundException $e) {
return response()->json([
'error' => $e->getMessage(),
'status_code' => 401
], 401);
}
break;
default :
try {
$user = User::where('email', $email)->firstOrFail();
} catch (ModelNotFoundException $e) {
return response()->json([
'error' => $e->getMessage(),
'status_code' => 401
], 401);
}
}
return compact('token', 'user');
}
}
- 认证请求必须包含
provider
键,这样系统就会知道要认证哪个用户
例如。
POST /api/oauth/token HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
grant_type=password&username=test%40email.com&password=secret&provider=customers
如果没有传递提供者参数,它将默认查找
users
表,就像通常一样。