1

如何添加DESC到默认登录 sql 查询?

我的意思是默认情况下是这样的

select * from users where name = user_name limit 1.

我该如何添加

select * from users where name = user_name ORDER BY id DESC limit 1?

我知道名称列应该只包含唯一值,我的登录系统不同(另一个表中的一些预定义用户),我需要多个具有相同名称的用户注册。我只想登录数据库中的最后一条记录。请帮助我如何在 laravel 中自定义模型提供程序?我不知道要修改哪些文件才能使其正常工作。

这是我的 LoginController.php 但你可以忽略它(我添加它是因为一些用户需要它)只需查看默认 loginController 来自php artisan make:auth

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Illuminate\Support\Facades\Session;
class LoginController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles authenticating users for the application and
    | redirecting them to your home screen. The controller uses a trait
    | to conveniently provide its functionality to your applications.
    |
    */

    use AuthenticatesUsers;

    /**
     * Where to redirect users after login.
     *
     * @var string
     */
    protected $redirectTo = '/home';

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }
/**
     * Check either username or email.
     * @return string
     */

public function login(Request $request)
    {
        $this->validateLogin($request);

        // If the class is using the ThrottlesLogins trait, we can automatically throttle
        // the login attempts for this application. We'll key this by the username and
        // the IP address of the client making these requests into this application.
        if ($this->hasTooManyLoginAttempts($request)) {
            $this->fireLockoutEvent($request);

            return $this->sendLockoutResponse($request);
        }

        if ($this->attemptLogin($request)) {
            return $this->sendLoginResponse($request);
        }

        // If the login attempt was unsuccessful we will increment the number of attempts
        // to login and redirect the user back to the login form. Of course, when this
        // user surpasses their maximum number of attempts they will get locked out.
        $this->incrementLoginAttempts($request);

        return $this->sendFailedLoginResponse($request);
    }

      public function username()
    {
        $identity  = Session::get('table_id');
        $fieldName = 'name';
        request()->merge([$fieldName => $identity]);

        return $fieldName;
    }

    /**
     * Validate the user login.
     * @param Request $request
     */
    protected function validateLogin(Request $request)
    {
        $this->validate(
            $request,
            [
                'password' => 'required|string',
            ],
            [
                'password.required' => 'Password is required',
            ]
        );
    }
    /**
     * @param Request $request
     * @throws ValidationException
     */
    protected function sendFailedLoginResponse(Request $request)
    {
        $request->session()->put('login_error', trans('auth.failed'));
        throw ValidationException::withMessages(
            [
                'error' => [trans('auth.failed')],
            ]
        );
    }

     protected function attemptLogin(Request $request)
    {
        $remember = true;
        return $this->guard()->attempt(         
            $this->credentials($request), $remember
        );
    }
}

我的 LoginController 中的所有方法都覆盖了来自vendor\laravel\framework\src\Illuminate\Foundation\Auth\AuthenticatesUsers.php

4

4 回答 4

2

将 LoginController 替换为以下内容。我已经删除了 username() 方法并替换了 attemptLogin() 方法来获取数据库中的最后一个用户,因为你的会话值为 'table_id'。

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Illuminate\Support\Facades\Session;
use App\User;
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles authenticating users for the application and
    | redirecting them to your home screen. The controller uses a trait
    | to conveniently provide its functionality to your applications.
    |
    */

    use AuthenticatesUsers;

    /**
     * Where to redirect users after login.
     *
     * @var string
     */
    protected $redirectTo = '/home';

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct(User $user)
    {
        $this->middleware('guest')->except('logout');
        $this->user = $user;
    }
/**
     * Check either username or email.
     * @return string
     */

public function login(Request $request)
    {
        $this->validateLogin($request);

        // If the class is using the ThrottlesLogins trait, we can automatically throttle
        // the login attempts for this application. We'll key this by the username and
        // the IP address of the client making these requests into this application.
        if ($this->hasTooManyLoginAttempts($request)) {
            $this->fireLockoutEvent($request);

            return $this->sendLockoutResponse($request);
        }

        if ($this->attemptLogin($request)) {
            return $this->sendLoginResponse($request);
        }

        // If the login attempt was unsuccessful we will increment the number of attempts
        // to login and redirect the user back to the login form. Of course, when this
        // user surpasses their maximum number of attempts they will get locked out.
        $this->incrementLoginAttempts($request);

        return $this->sendFailedLoginResponse($request);
    }

    /**
     * Validate the user login.
     * @param Request $request
     */
    protected function validateLogin(Request $request)
    {
        $this->validate(
            $request,
            [
                'password' => 'required|string',
            ],
            [
                'password.required' => 'Password is required',
            ]
        );
    }
    /**
     * @param Request $request
     * @throws ValidationException
     */
    protected function sendFailedLoginResponse(Request $request)
    {
        $request->session()->put('login_error', trans('auth.failed'));
        throw ValidationException::withMessages(
            [
                'error' => [trans('auth.failed')],
            ]
        );
    }

protected function attemptLogin(Request $request, User $user)
{
    if (session()->has('table_id') != true) return redirect()->back()->withErrors(['error' => 'No username is set.']);
    $userName = $user->where('name', session('table_id'))->orderBy('id', 'desc')->first()->name;
    $remember = true;
    if (Auth::attempt(['name' => $userName, 'password' => request('password')], $remember)) {
        return redirect()->intended();
    }
}

}
于 2018-07-11T13:36:28.313 回答
0

您不应更改/删除任何框架文件和代码。在您的登录控制器顶部添加此特征:

use AuthenticatesUsers;

然后您可以覆盖所有登录功能。

为了验证用户名/密码,只需覆盖尝试登录()函数。

于 2018-07-11T14:26:18.970 回答
0

因此,如果我正确理解您的问题,您希望在身份验证时更改默认 sql 查询以选择用户。在attemptLogin您调用的方法attempt中,它在 StatefulGuard 接口中并且实现在其中,/vendor/laravel/framework/src/Illuminate/Auth/SessionGuard.php因此您需要覆盖完整attempt方法,或者其中的方法。

于 2018-07-11T15:38:55.160 回答
0

我找到了另一种可行的解决方案,但我相信它会搞砸一些事情(我不确定),这就是为什么我将 Polaris 的答案选为正确答案的原因。

您可以保留默认的 LoginController 并像这样修改 App/User.php:它基本上覆盖retrieveByCredentialsIlluminate\Auth\EloquentUserProvider;. 问题是我相信这个方法通常不会直接从 访问,Users.php所以你不会直接覆盖它。但由于某种原因它有效:))。

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Auth\EloquentUserProvider;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

        public function retrieveByCredentials(array $credentials)
    {
        if (empty($credentials) ||
           (count($credentials) === 1 &&
            array_key_exists('password', $credentials))) {
            return;
        }

        // First we will add each credential element to the query as a where clause.
        // Then we can execute the query and, if we found a user, return it in a
        // Eloquent User "model" that will be utilized by the Guard instances.
        $query = $this->createModel()->newQuery();

        foreach ($credentials as $key => $value) {
            if (Str::contains($key, 'password')) {
                continue;
            }

            if (is_array($value) || $value instanceof Arrayable) {
                $query->whereIn($key, $value);
            } else {
                $query->where($key, $value);
            }
        }

       return $query->orderBy('id', 'desc')->first();
    }
}
于 2018-07-12T09:41:24.043 回答