Auth::attempt 值始终为 false

Posted

技术标签:

【中文标题】Auth::attempt 值始终为 false【英文标题】:Auth::attempt value always false 【发布时间】:2020-07-25 17:50:42 【问题描述】:

我想登录时遇到了一些问题,我的Auth::attempt 总是错误的值有问题,我的代码有问题吗?

控制器:

public function register(Request $register)

    $validator = Validator::make($register->all(), [
        'name' => 'required',
        'email' => 'required|email',
        'password' => 'required',
    ]);
    if ($validator->fails()) 
        return response()->json(['error' => $validator->errors()], 401);
     else 
        $name = $register->input('name');
        $email = $register->input('email');
        $pwd = $register->input('password');
        $c_pwd = $register->input('c_password');

        // Crypting password & c_password to md5
        $md5_pwd = md5($pwd);
        $md5_c_pwd = md5($c_pwd);

        // Salt password & c_password 
        $password = crypt($md5_pwd, "asd");
        $c_password = crypt($md5_c_pwd, "asd");

        $data = new User();

        if ($password == $c_password) 
            $user = User::create([
                'name' => $name,
                'email' => $email,
                'password' => $password,
            ]);
            $success['token'] = $user->createToken('SSOApp')->accessToken;
            return response()->json([
                'success' => true,
                'token' => $success,
                'user' => $user
            ]);
         else 
            return response()->json(['error' => "Password doesn't match"], 401);
        
    


public function login()

    $email = request('email');
    $pwd = request('password');
    $md5 = md5($pwd);
    $password = crypt($md5, "asd");
    if (Auth::attempt(['email' => $email, 'password' => $password])) 
        $user = Auth::user();
        $success['token'] = $user->createToken('SSOApp')->accessToken;
        return response()->json([
            'success' => true,
            'token' => $success,
            'user' => $user
        ]);
     else 
        return response()->json([
            'success' => false,
            'message' => 'Invalid Email or Password',
        ], 401);
    

【问题讨论】:

不推荐使用 md5() 而不是 bcrypt()。和 Auth::attempt 使用 bcrypt 检查用户密码。 那么我必须为我的 md5() 和 bcrypt() 使用方法做什么? 尽可能不要使用自己的加密。在保存用户密码的同时调用 Hash::make('string') 使用 laravel 默认 bcrypt()。 所以只使用 bcrypt 的默认方法?无法使用其他方法? 您可以通过在 config/hash.php 文件中指定驱动程序来使用其他驱动程序“bcrypt”、“argon”、“argon2id”进行散列,因为它们目前支持这 3 个驱动程序。因此,如果您想使用 laravel 默认的身份验证系统,请使用其中之一,否则创建您自己的身份验证系统(md5,或任何您想要的) 【参考方案1】:

我假设你搞砸了 Laravel 默认密码哈希系统

public function register(Request $register)

    $validator = Validator::make($register->all(), [
        'name' => 'required',
        'email' => 'required|email',
        'password' => 'required',
        'c_password' => 'required|same:password',
    ]);
    if ($validator->fails()) 
        return response()->json(['error' => $validator->errors()], 401);
     else 
        $name = $register->input('name');
        $email = $register->input('email');
        $pwd = $register->input('password');
        $c_pwd = $register->input('c_password');


        // $data = new User();

        $user = User::create([
                'name' => $name,
                'email' => $email,
                'password' => bcrypt($password . 'salt'),
        ]);

        $success['token'] = $user->createToken('SSOApp')->accessToken;
        return response()->json([
                'success' => true,
                'token' => $success,
                'user' => $user
        ]);

    


public function login()

    $email = request('email');
    $pwd = request('password');

    if (Auth::attempt(['email' => $email, 'password' => $password . 'salt'])) 
        $user = Auth::user();
        $success['token'] = $user->createToken('SSOApp')->accessToken;
        return response()->json([
            'success' => true,
            'token' => $success,
            'user' => $user
        ]);
     else 
        return response()->json([
            'success' => false,
            'message' => 'Invalid Email or Password',
        ], 401);
    

【讨论】:

好的,这是工作,但我有一些问题,如果我使用 crypt($password, "salt")bcrypt($password . "salt") 是不同的方法? 简短回答:是的。但是,我在文档中找不到任何关于 Laravel 中 crypt 用法的参考 哈哈,谢谢,因为我从 CI 迁移到 Laravel,我认为 laravel 有一个类似于 CI 的 crypt,但不同的框架有不同的方法【参考方案2】:

试试这个代码。我不知道您在attempt 中尝试加密的密码发生了什么变化。

public function login(LoginRequest $request) 
      if(!Auth::attempt([
        'email' => $request->email,
        'password' => $request->password,
        'active' => true
      ])) 
        return response()->json('Email or Password is incorrect', 500);
      

      $this->user = Auth::user()->load('roles');
      return $this->createUserAccessTokenResponse();
    

protected function createUserAccessTokenResponse() 
      return response()->json([
        'status' => 'success',
        'data' => [
          'token' => $this->user->createToken($this->user->name)->accessToken,
          'user' => $this->user
        ],
      ], 200);
    

【讨论】:

【参考方案3】:

你的问题是 laravel 默认散列密码。因此,当您执行Auth::attempt 时,它将对您提供的密码进行哈希处理。结果就是你得到的,它永远是假的。

相反,您需要Other Authentication Methods。

Auth::login($user);

// Login and "remember" the given user...
Auth::login($user, true);

以上是修复代码的最简单方法。

建议对您的密码进行哈希处理,而不是对密码进行加密。

laravel 中的哈希密码也是

Hash::make($password);

然后您可以使用Auth::attempt 登录您的用户。

【讨论】:

【参考方案4】:

Laravel Auth 在通过模型保存密码时使用 bcrypt 哈希,您可以使用两种方法中的任何一种

$account->password = bcrypt("YOUR_PASSWORD");$account->password = Hash::make("YOUR_PASSWORD");

如果你正在处理 auth attempt 函数,只需简单地调用这样的方法

if($account = Auth::attemp(['email' => "YOUR_EMAIL@DOMAIN.COM",  'password' => "YOUR_PASSWORD"]))
    //success login, do your extra job here
else
    //invalid credentials here

【讨论】:

【参考方案5】:

而不是使用md5crypt 使用\Hash::make() 它更安全 我重构了你的代码,它做了同样的事情 您只需将c_password 重命名为password_confirmationSource 下面的代码和你的代码做同样的事情

public function register(Request $register)

    $this->validate($register, [
        'name' => 'required',
        'email' => 'required|email',
        'password' => 'required|confirmed',
    ]);

    $user = User::create([
        'name' => $register->input('name'),
        'email' => $register->input('email'),
        'password' => $register->input('password'),
    ]);
    $success['token'] = $user->createToken('SSOApp')->accessToken;

    return response()->json([
        'success' => true,
        'token' => $success,
        'user' => $user,
    ]);


public function login(Request $request)

    $request->merge(['password' => \Hash::make($request->input('password'))]);

    if (Auth::attempt($request->only(['email', 'password']))) 
        $user = Auth::user();
        $success['token'] = $user->createToken('SSOApp')->accessToken;

        return response()->json([
            'success' => true,
            'token' => $success,
            'user' => $user,
        ]);
    

    return response()->json([
        'success' => false,
        'message' => 'Invalid Email or Password',
    ], 401);

当您使用 crypt 对密码进行哈希处理时,它有一个解锁密码的密钥,这就是为什么有一个 decrypt 但是当您使用 Hash::make() 它没有破解或解锁它的密钥时,它会检查它算法来查看给定的密码是否与数据库中已经存在的算法相匹配,这就是为什么crypt 不安全而 Hash::make 更安全

【讨论】:

我只使用默认的 bcrypt 没有什么不同?然后在注册函数里面bcrypt用来加密密码? 我更新了我的答案并描述了为什么 hash::make 更好

以上是关于Auth::attempt 值始终为 false的主要内容,如果未能解决你的问题,请参考以下文章

Laravel Auth::attempt() 返回 false

Laravel Auth::attempt 会话过期

Laravel 4 - Auth::attempt() 不工作

在 Auth::attempt() Laravel 5.1 中禁用重定向

Laravel 5 Auth::attempt() 总是返回 false

Laravel 4 Auth::attempt($userdata, false) 身份验证仍然保留