Php 用户名是必需的错误,即使我在Laravel中发送用户名

Php 用户名是必需的错误,即使我在Laravel中发送用户名,php,laravel,Php,Laravel,我用的是护照和Laravel的验证器 这是我的登录控制器: public function login (Request $request) { $validator = Validator::make($request->all(), [ 'username' => 'required|string|max:255', 'password' => 'required|string|min:6', ]); if ($va

我用的是护照和Laravel的验证器

这是我的登录控制器:

public function login (Request $request) {
    $validator = Validator::make($request->all(), [
        'username' => 'required|string|max:255',
        'password' => 'required|string|min:6',
    ]);

    if ($validator->fails()) {
        return response(['errors'=>$validator->errors()->all()], 422);
    }

    $user = User::where('username', $request->username)->first();
    if ($user) {
        if (Hash::check($request->password, $user->password)) {
            $token = $user->createToken('Laravel Password Grant Client')->accessToken;
            $response = ['token' => $token];
            return response($response, 200);
        } else {
            $response = ["message" => "Password mismatch"];
            return response($response, 422);
        }
    } else {
        $response = ["message" =>'User does not exist'];
        return response($response, 422);
    }
}
这是我的
路由/api.php

use App\Http\Controllers\Auth\ApiAuthController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

Route::group(['middleware' => ['cors', 'json.response']], function () {
    Route::post('/login', [ApiAuthController::class, 'login']);
    Route::post('/register', [ApiAuthController::class, 'register']);
    Route::post('/logout', [ApiAuthController::class, 'logout']);
});
以下是
请求

POST http://localhost:8080/api/login
Accept: application/json
Content-Type: application/json

{
    "username": "sundowatch",
    "password": "12345678",
}
但它返回以下错误:

HTTP/1.1 422 Unprocessable Entity
Host: 127.0.0.1:8080
Date: Sat, 24 Apr 2021 17:35:31 GMT, Sat, 24 Apr 2021 17:35:31 GMT
Connection: close
X-Powered-By: PHP/7.3.26
Cache-Control: no-cache, private
Content-Type: application/json
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: X-Requested-With, Content-Type, X-Token-Auth, Authorization
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 57

{
  "errors": [
    "The username field is required.",
    "The password field is required."
  ]
}

我将与您分享一些小技巧,以获得更清晰的代码,所以不要把这看作是一个坏的批评者,只是一个建设性的批评

使用
illumb\Support\Facades\Validator
而不是
illumb\Validation\Validator
,您将能够使用
Validator::validate()
而不是
Validator::make()
,然后使用
$Validator->fails()
,这样做已经删除了至少3行代码,而且更清晰

使用light\Support\Facades\Validator;
Validator::validate($request->all()[
'username'=>'必需|字符串|最大值:255',
'密码'=>'必需|字符串|最小值:6',
]);
这将在所有数据中抛出一个错误(
ValidationException
),与您所做的一样(
errors=>all errors
),并返回
422
。因此,如果,您可以完全删除

Validator::validate($request->all()[
'username'=>'必需|字符串|最大值:255',
'密码'=>'必需|字符串|最小值:6',
]);
$user=user::where('username',$request->username)->first();
如果($user){
如果(哈希::检查($request->password,$user->password)){
$token=$user->createToken('Laravel密码授予客户端')->accessToken;
$response=['token'=>$token];
答复(答复,200美元);
}否则{
$response=[“message”=>“密码不匹配”];
答复($答复,422);
}
}否则{
$response=[“message”=>“用户不存在”];
答复($答复,422);
}
您仍然可以执行
$validated=Validator::validate(…)
,如果失败,它将返回错误,但如果通过,它将只存储已验证的字段(
用户名
密码
在这种情况下,如果用户发送的
是\u admin=1
,它将被忽略,因此您将拥有
$validated['username']
$validated['password']
)因此,这可以防止我们使用其他未经验证的输入造成混乱,比如说,您忘记验证输入,并且您执行了
$request->is_admin
,因此,如果您只使用
$validated
,您肯定只会使用
规则
部分中存在的字段。目前,我将忽略这一点,继续使用
$request

然后我们可以重新排列
$user
和下一个
if
。您可以使用
firstOrFail()
而不是
first()
,这样,您就可以删除
else
,只需要一个没有
if else
的代码。它看起来像:

Validator::validate($request->all()[
'username'=>'必需|字符串|最大值:255',
'密码'=>'必需|字符串|最小值:6',
]);
$user=user::where('username',$request->input('username')->firstOrFail();
如果(哈希::检查($request->password,$user->password)){
$token=$user->createToken('Laravel密码授予客户端')->accessToken;
$response=['token'=>$token];
答复(答复,200美元);
}否则{
$response=['message'=>'密码不匹配'];
答复($答复,422);
}
然后,您还可以更改最后一个
(如果其他
)。我建议您阅读有关
If-guard子句的内容

所以,你可以这样做:

Validator::validate($request->all()[
'username'=>'必需|字符串|最大值:255',
'密码'=>'必需|字符串|最小值:6',
]);
$user=user::where('username',$request->input('username')->firstOrFail();
如果(!Hash::check($request->input('password'),$user->password)){
返回响应(['message'=>'密码不匹配'],422);
}
$token=$user->createToken('Laravel密码授予客户端')->accessToken;
返回响应(紧凑(“令牌”);
请注意:

  • 我已经更改了
    if
    逻辑,多亏了
    guard子句
    ,我们正在反转子句,因此我们只在不希望发生/已经发生的事情时才退出
  • 我直接用值替换了
    $response
    ,我不喜欢创建值,然后在下一行返回值时使用它们。(这是非常个人化的,仍然可以看到我们如何通过这样做减少了大量代码,并且乍一看仍然可读性和可理解性)
  • 我用
    ->input('username')
    ->input('password')
    更改了
    $request->username>和
    $request->password
    。你可以看到两者的源代码,它们几乎是一样的,我只是更喜欢使用
    input
    ,因为我会理解这是100%的laravel,但是如果你使用
    ->username
    ,它可能是你使用过的macroed或类似的东西。同样,这是个人的
  • 最后一行,我有:
    • 已删除
      200
      ,因为它是默认值,并且始终用于
      响应
      ,无需再次写入,我们知道它是默认值,因为它是一个良好的响应,没有错误
    • 再次替换为
      ['token=>$token]
      ,但在本例中为。这也是个人的选择,但使用两种方法是一样的。我只是想改变它,让所有不知道compact的人现在就可以学习它,将来也可以使用它

  • 因此,将您的原始代码与新代码进行比较,新代码功能相同,但更小,可读性更强:

    $validator=validator::make($request->all()[
    'username'=>'必需|字符串|最大值:255',
    '密码'=>'必需|字符串|最小值:6',
    ]);
    如果($validator->fails()){
    返回响应(['errors'=>$validator->errors()->all()],422);
    }
    $user=user::where('username',$request->username)->first();
    如果($user){
    如果(哈希::检查($request->password,$user->password)){
    $token=$user->createToken