具有多个模型的 Jwt

Posted

技术标签:

【中文标题】具有多个模型的 Jwt【英文标题】:Jwt with multiple model 【发布时间】:2017-01-14 18:58:23 【问题描述】:

我使用带有 jwt 的 Lavarel 5.2 框架进行授权 jwt 仅使用一种模型获取用户信息表单令牌, 现在如何在多个模型上使用 jwt 解析用户令牌? 例如,当我在 api jwt 中使用客户令牌从客户模型中解析该令牌时,默认守卫应该是客户 auth.php

'defaults' => [
    'guard' => 'operator',
    'passwords' => 'operators',
],

'guards' => [
    'operator' => [
        'driver' => 'session',
        'provider' => 'operators',
    ],
    'customer' => [
        'driver' => 'session',
        'provider' => 'customers',
    ],
    'biker' => [
        'driver' => 'session',
        'provider' => 'bikers',
    ]
],

'providers' => [
    'operators' => [
        'driver' => 'eloquent',
        'model' => App\Http\Services\Auth\Model\User::class,
    ],
    'customers' => [
        'driver' => 'eloquent',
        'model' => App\Http\Aggregate\Customer\Model\Customer::class,
    ],
    'bikers' => [
        'driver' => 'eloquent',
        'model' => App\Http\Aggregate\Biker\Model\Biker::class,
    ]
],

【问题讨论】:

请朋友们帮帮我 你的问题很不清楚。考虑一下如何将其改写为人们可以帮助您的内容。 现在我想清楚了 感谢分数的朋友,但我希望你能帮助我解决这个问题:) 【参考方案1】:

兼容 Laravel 8

对于仍在寻找干净解决方案的其他人:

我建议在 config/auth.php 中手动配置提供程序和守卫,不要以编程方式更改任何提供程序。

接下来要确保使用正确的 JWTSubject 身份验证模型,是为一组只能访问的路由创建不同的中间件(不要忘记在 Kernel.php 中的$routeMiddleware 下指定它)通过特定的守卫/身份验证模型。然后,对于 Manager 模型,中间件句柄函数可能如下所示:

public function handle(Request $request, Closure $next) 
    if (!($request->user('managers'))) abort(401);

    Auth::shouldUse('managers');

    return $next($request);

然后为 Employee 模型创建另一个中间件,并将 'managers' 保护值更改为您在 config/auth.php 中配置的 'employees'。

在您的 routes/api.php 中,您可以使用(例如)指定路由组:

Route::group(['middleware' => 'management'], function()  );

为了使这一切正常工作,请在调用 auth()->attempt() 函数时指定保护,例如auth('managers')->attempt($credentials)).

【讨论】:

【参考方案2】:

这是我的解决方案。在 Laravel 6 上测试

用户模型

namespace App;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\SoftDeletes;
use Tymon\JWTAuth\Contracts\JWTSubject;

class User extends Authenticatable implements JWTSubject

    use SoftDeletes;
    use Notifiable;

    public $incrementing = false;
    protected $keyType = 'string';

    protected $fillable =
    [
    
    ];

    protected $hidden =
    [
        'password',
        'created_at',
        'updated_at',
        'deleted_at'
    ];

    public function getJWTIdentifier()
    
        return $this->getKey();
    

    public function getJWTCustomClaims()
    
      
    

教师模型

namespace App;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\SoftDeletes;
use Tymon\JWTAuth\Contracts\JWTSubject;

class Teacher extends Authenticatable implements JWTSubject

    use SoftDeletes;
    use Notifiable;

    public $incrementing = false;
    protected $keyType = 'string';

    protected $fillable =
    [
       
    ];

    protected $hidden =
    [
        'password',
        'oldpassword',
        'created_at',
        'updated_at',
        'deleted_at'
    ];

    public function getJWTIdentifier()
    
        return $this->getKey();
    

    public function getJWTCustomClaims()
    
       
    

配置/auth.php

'defaults' => [
        'guard' => 'api',
        'passwords' => 'users',
    ],
'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        'api' => [
            'driver' => 'jwt',
            'provider' => 'users'
        ],
        'teacher-api' => [
            'driver' => 'jwt',
            'provider' => 'teachers'
        ],
    ],

AuthController 功能:

   if (
        $request->getRequestUri() ===
        'OTHER_AUTH_ROUTE'
    ) 
        $credentials = $request->only('username', 'password']);
        $token = Auth::shouldUse('teacher-api');
        $token = Auth::attempt($credentials);
        if (!$token) 
            return response()->json(['error' => 'Unauthorized'], 401);
        
        return $this->respondWithToken($token);
    
    $credentials = $request->only([USERNAME, 'password']);
    $token = Auth::attempt($credentials);
    if (!$token) 
        return response()->json(['error' => 'Unauthorized'], 401);
    
    return $this->respondWithToken($token);

希望对大家有所帮助

【讨论】:

【参考方案3】:

您可以在每个控制器中更改__construct 函数,如下所示。以便 jwt 知道要验证哪个模型。

自行车控制器

function __construct()

    Config::set('jwt.user', Biker::class);
    Config::set('auth.providers', ['users' => [
            'driver' => 'eloquent',
            'model' => Biker::class,
        ]]);

客户控制器

function __construct()

    Config::set('jwt.user', Customer::class);
    Config::set('auth.providers', ['users' => [
            'driver' => 'eloquent',
            'model' => Customer::class,
        ]]);

【讨论】:

【参考方案4】:

您可以创建一个单独的中间件,例如 AuthModel。您可以设置配置以采用如下提供者,

Config::set('auth.providers.users.model',\App\Models\Customer::class);

如果要使用多个模型,则需要使用 if 条件来检查哪个 url 可以访问哪些模型。可以这样,

if(url == '/customer/api/') 
 Config::set('auth.providers.users.model',\App\Models\Customer::class);
 else if(url == '/biker/api/') 
 Config::set('auth.providers.users.model',\App\Models\Biker::class);

在上面的例子中,我只是使用了url作为例子,所以从请求中获取它。

【讨论】:

您好,请您查看与您的答案相关的这个问题并告诉我您对此有何看法Here

以上是关于具有多个模型的 Jwt的主要内容,如果未能解决你的问题,请参考以下文章

具有相同令牌的多个 Laravel-API 的 JWT 身份验证

如何在 asp.net core 2.0 中允许具有不同发行者的多个 JWT

具有多个身份验证源的JWT令牌

基于 JWT 身份验证和角色在 Express 中路由到多个 Angular 7 项目

在具有分页的单个模型查询代码点火器中获取具有多个条件的多个连接结果

Flutter 使用具有作用域模型的多个模型