【问题标题】:Auth::Check is always false but successfully authenticates - Laravel 8Auth::Check 始终为假但成功验证 - Laravel 8
【发布时间】:2021-05-27 20:30:30
【问题描述】:

我目前正在尝试学习 Laravel,但遇到了身份验证问题。我正在尝试创建一个仅 API 的 laravel 项目,我没有使用任何 Vue 或 Blade 模板文件,并且暂时关闭了 CSRF 验证,因为我认为这在使用 Insomnia Rest 时也会导致我出现一些问题API 客户端(只是想初步了解基础知识)。

我有两个简单的 API 路由,一个用于登录,另一个用于检查我是否已登录并返回用户详细信息。

我正在使用自己的数据库和用户模型进行身份验证。

我的用户模型如下:

<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;

class Users extends Authenticatable
{
    use HasFactory;

    protected $table = "users";
    protected $primaryKey = "UserID";

    protected $casts = [
        "IsActive" => "boolean"
    ];
}

在我的 api.php 中,我有以下内容

Route::prefix("/login") ->group(__DIR__ . '/login.php');

然后在 login.php 我有以下内容

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\LoginController;
Route::post('/', [LoginController::class, 'login']);
Route::get('/', [LoginController::class, 'getLoggedInUser']);

我的 LoginController 类设置如下:

namespace App\Http\Controllers;

use App\Models\Users as User;
use Illuminate\Http\Request;

class LoginController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth:api')->except('login', 'getLoggedInUser');
        //$this->middleware('admin')->except('login', 'forgot', 'getLoggedInUser');
    }

然后在我的 LoginController 中,我有以下登录请求以实际执行身份验证:

public function login(Request $request)
    {
        $user = User::where("Username", "my_username")->where("Password", "my_password")->first();

        if ($user !== null)
        {
            if ($user->AccountActive)
            {
                \Auth::login($user);
                
                return \response(["status" => "authenticated", "auth'd user" => \Auth::user(), "logged_in" => \Auth::check()], 200);
            }
            else
            {
                return \response(["status" => "Your account has been disabled"], 401);
            }
        }
        else
        {
            return \response(["status" => "failed"], 401);
        }
    }

正如您在上面看到的,我目前正在使用数据库中的字符串值对用户凭据进行硬编码,而不是当前检查请求中的任何内容。

以上登录返回如下响应:

{
  "status": "authenticated",
  "auth'd user": {
    "UserID": 1,
    "LastLoggedIn": "2020-01-16 18:29:37",
    "Username": "my_username",
    "Password": "my_password",
    "AuthToken": "0",
    "Email": "",
    "AccountActive": "1"
  },
  "logged_in": true
}

在我检查我是否登录路由时,我有以下内容:

public function getLoggedInUser(Request $request)
    {
        return [
            "logged_in" => \Auth::check(),
            "status" => "success",
            "user" => \Auth::user()
        ];
    }

当我执行上述操作时,我会得到以下响应:

{
  "logged_in": false,
  "status": "success",
  "user": null
}

所以你可以看到它的行为就像我不再经过身份验证一样。

【问题讨论】:

  • User::where("Username", "my_username")-&gt;where("Password", "my_password") 为什么要在数据库中存储明文密码? Laravel 提供了一个名为 Breeze 的身份验证框架。使用它!
  • 刚刚注意到这是针对 API 身份验证,而不是用户身份验证。此功能不再记录,但在 Laravel 8 中仍然有效:laravel.com/docs/5.8/api-authentication。使用散列避免在数据库中存储明文密码。
  • 我当然不会存储纯文本密码。我只想获得使用现有数据库的基础知识。我当然没有在 SO 帖子中提供实际的密码字符串!

标签: php laravel authentication


【解决方案1】:

HTTP 请求是无状态的,为了解决这个问题,例如会话用于存储请求之间的状态。即使您已经通过登录验证了自己,但在任何地方都没有保留任何状态来将请求与您关联。

API 不使用会话,因此您需要一些其他机制与每个后续请求一起发送,服务器可以检查这些请求以确定谁发出了请求以及他们是否有权执行请求的操作。

对于 Laravel,这就是 SanctumPassport 包的用武之地。它们为 API 提供身份验证工作流。

虽然每个人的学习历程都不同,而且人们的学习方式也不同,但我觉得你可能会因为避免使用 Laravel 提供的软件包而使学习 Laravel 变得更加困难。毕竟,使用 Laravel 或任何类型的框架的原因之一是利用它提供的功能来简化你的生活。

【讨论】:

  • 谢谢。我会再次检查这些包裹,我确实看过它们,但似乎有点矫枉过正,但可能被误解了。我正在查看另一个项目为 auth 做类似的事情,看起来他们没有使用 composer 文件中的任何一个包,将再次检查。一定是在某处遗漏了什么
  • @Boardy Sanctum 曾经被称为 Airlock,是 API 的轻量级身份验证流程。 Passport 是一个功能齐全的 OAuth 实现,对于大多数人的自用 API 实现来说可能有点矫枉过正。人们经常使用的另一个包是tymon/jwt 包。我建议先检查圣所。大量的在线教程也涵盖了它。
猜你喜欢
  • 2015-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-22
  • 1970-01-01
  • 1970-01-01
  • 2021-07-29
相关资源
最近更新 更多