Laravel 全局范围认证

Posted

技术标签:

【中文标题】Laravel 全局范围认证【英文标题】:Laravel Global Scope Auth 【发布时间】:2016-04-14 06:18:11 【问题描述】:

我在用户模型中创建了一个匿名全局范围,如下所示,以便在前端仅获取公共用户:

protected static function boot()

    parent::boot();

    static::addGlobalScope('is_public', function(Builder $builder) 
        $builder->where('is_public', '=', 1);
    );

但是...当我需要在后端执行登录时,我当然需要检查非公共用户,所以我需要排除全局范围。

是否可以使用 laravel 默认的 AuthController?

非常感谢!!

【问题讨论】:

【参考方案1】:

您只需要创建两个模型 - 一个没有全局范围(即 AuthUser),另一个具有扩展第一个全局范围的全局范围(即用户)。

然后您可以使用 AuthUser 进行身份验证和其他任何地方的用户。

【讨论】:

这是处理此问题的好方法,此外,它将身份验证功能与用户功能分开【参考方案2】:

您可以使用以下方法即时删除任何全局范围:

User::withoutGlobalScope('is_public')->get();

【讨论】:

【参考方案3】:

我通过创建新包解决了这个问题。

mpyw/scoped-auth: Apply specific scope for user authentication.

运行composer require mpyw/scoped-auth 并像这样修改您的用户模型:

<?php

namespace App;

use Illuminate\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Authenticatable as UserContract;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Mpyw\ScopedAuth\AuthScopable;

class User extends Model implements UserContract, AuthScopable

    use Authenticatable;

    public function scopeForAuthentication(Builder $query): Builder
    
        return $query->where('is_public', '=', 1);
    

仅此而已。

【讨论】:

【参考方案4】:

要么创建两个单独的模型,我更愿意在全局范围内设置条件,因为如果您想从两个模型访问关系方法,那么您需要在两个模型中包含这些方法,或者您必须将一个模型扩展到另一个模型.我认为这不是一个好的解决方案。

为全局范围创建新文件:

<?php

namespace App\Scopes;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;
use Illuminate\Support\Facades\Auth;

class IsPublicScope implements Scope

    public function apply(Builder $builder, Model $model)
    
        if (Auth::hasUser()) 
            $builder->where('is_public', '=', 1);
        
    
    
?>

并将此方法添加到您的用户模型中:

protected static function boot()

    parent::boot();
    static::addGlobalScope(new IsPublicScope());

感谢@mpyw 的更正。

【讨论】:

未经Auth::hasUser() 检查,请勿致电Auth::check()。参考这个:***.com/questions/41824174/… Auth::user 或 Auth::hasUser 将始终在此处返回 false,因为调用启动时会话尚未初始化

以上是关于Laravel 全局范围认证的主要内容,如果未能解决你的问题,请参考以下文章

Laravel:具有 whereHas 和多对多关系的全局范围

在 Laravel 5.5 中根据用户角色应用全局范围

Laravel 在方法启动后有条件地添加全局范围

使用 laravel 范围避免歧义

学渣也要搞 laravel—— 安装篇

Laravel 的登录认证