在我的Laravel应用中,用户可以禁用(不删除)他们的帐户以从网站上消失。但是,如果他们尝试再次登录,则应自动激活他们的帐户,他们应该成功登录。
这是通过" active" users表中的列和User模型中的全局范围:
protected static function boot() {
parent::boot();
static::addGlobalScope('active', function(Builder $builder) {
$builder->where('active', 1);
});
}
现在的问题是那些非活动帐户无法再次登录,因为AuthController找不到它们(超出范围)。
我需要实现的目标:
我现在的想法是使用withoutGlobalScope找到用户,手动验证密码,更改列"活动"到1,然后进行常规登录。
在我的authController中使用postLogin方法:
$user = User::withoutGlobalScope('active')
->where('username', $request->username)
->first();
if($user != null) {
if (Hash::check($request->username, $user->password))
{
// Set active column to 1
}
}
return $this->login($request);
所以问题是如何在不改变Laravel主代码的情况下使AuthController忽略全局范围,因此它将保留更新?
感谢。
答案 0 :(得分:0)
创建一个扩展[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult NuevoProveedor(HttpPostedFileBase file, SubirArchivoModelo model)
{
SubirArchivoModelo modelo = new SubirArchivoModelo();
if (file != null)
{
string Ruta = file.FileName;
return View();
}
else
{
ViewBag.error = "No se pudo generar la carpeta, comunicate con Soporte Tecnico";
return View("UsuarioNuevo");
}
}
的类GlobalUserProvider
,如下所示
EloquentUserProvider
在class GlobalUserProvider extends EloquentUserProvider {
public function createModel() {
$model = parent::createModel();
return $model->withoutGlobalScope('active');
}
}
中注册您的新用户提供商:
AuthServiceProvider
最后,您应该在Auth::provider('globalUserProvider', function ($app, array $config) {
return new GlobalUserProvider($this->app->make('hash'), $config['model']);
});
配置文件中将用户提供程序驱动程序更改为globalUserProvider。
auth.php
答案 1 :(得分:0)
protected static function boot()
{
parent::boot();
if (\Auth::check()) {
static::addGlobalScope('active', function(Builder $builder) {
$builder->where('active', 1);
});
}
}
请尝试解决登录问题,您可以在登录后使用withoutGlobalScopes()
进行激活。
答案 2 :(得分:0)
用您在OP中使用的代码扩展AuthController
。应该可以。
public function postLogin(Request $request)
{
$user = User::withoutGlobalScope('active')
->where('username', $request->username)
->first();
if($user != null){
if (Hash::check($request->password, $user->password)){
$user->active = 1;
$user->save();
}
}
return $this->login($request);
}
答案 3 :(得分:0)
@Sasan的答案在Laravel 5.3中效果很好,但在5.4中效果不佳-createModel()期望一个Model
但得到一个Builder
对象,所以当EloquentUserProvider
调用{{ 1}}引发异常:
$model->getAuthIdentifierName()
相反,请遵循相同的方法,但要覆盖更多功能,以便从BadMethodCallException: Call to undefined method Illuminate\Database\Query\Builder::getAuthIdentifierName() in /var/www/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2445
返回正确的对象。
createModel()
返回不具有全局范围的构建器,该范围由其他两个函数使用。
getQuery()
答案 4 :(得分:0)
我通过创建新软件包来解决它。
mpyw/scoped-auth: Apply specific scope for user authentication.
运行clear = lambda: os.system('clear')
clear()
并按如下所示修改您的用户模型:
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->withoutGlobalScope('active');
}
}
在监听器上激活用户。
Illuminate\Auth\Events\Login
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Event;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
\Illuminate\Auth\Events\Login::class => [
\App\Listeners\ActivateUser::class,
],
];
/**
* Register any events for your application.
*
* @return void
*/
public function boot()
{
parent::boot();
//
}
}
答案 5 :(得分:0)
Sasan Farrokh的回答正确。唯一不用重写 createModel 而是重写 newModelQuery 的方法就可以了
protected function newModelQuery($model = null)
{
$modelQuery = parent::newModelQuery();
return $modelQuery->withoutGlobalScope('active');
}
答案 6 :(得分:0)
我不得不使用
->withoutGlobalScopes()
代替
为了让它工作