Auth::logoutOtherDevices 导致密码错误问题

注:经 [@ALMAS](https://learnku.com/users/7036) 提醒,发现user模型中有定义一个修改器,用于密码处理,问题出在该处,并非laravel 问题。特此纠正,感谢 [@ALMAS](https://learnku.com/users/7036) 的提醒。
代码如下:

 public function setPasswordAttribute($value)
    {
        $value = str_replace(' ', '', $value);
        $this->attributes['password'] = bcrypt($value);
    }

以上纠正于:2019年7月16日 20:32分!

最近做开发的时候,要求实现单设备登录功能,看了下文档,发现 Auth::logoutOtherDevices($password) 正好满足条件。于是兴冲冲的使用了该方法。结果悲剧了, 账号登录后,Auth::logoutOtherDevices 处理完,再想登录的时候,报密码错误。找问题发现使用 Auth::logoutOtherDevices 后,数据库中的密码变了,用 password_verify 去验证数据库中改变后的密码,死活验证不通过。 好嘛,只能跟踪源码找问题了。

     /**
     * Invalidate other sessions for the current user.
     *
     * The application must be using the AuthenticateSession middleware.
     *
     * @param  string  $password
     * @param  string  $attribute
     * @return bool|null
     */
    public function logoutOtherDevices($password, $attribute = 'password')
    {
        if (! $this->user()) {
            return;
        }

        $result = tap($this->user()->forceFill([
          **$attribute => Hash::make($password),** 
        ]))->save();

        if ($this->recaller() ||
            $this->getCookieJar()->hasQueued($this->getRecallerName())) {
            $this->queueRecallerCookie($this->user());
        }

        $this->fireOtherDeviceLogoutEvent($this->user());

        return $result;
    }

在该方法中,发现密码是Hash::make加密后存储。刚开始以为是这里加密方式问题,后来经测试发现不是。真正的原因是密码被加密了两次,$attribute => Hash::make($password) 加密了一次,在入库的时候又做了一次hash,最终导致密码验证不通过。找到问题就简单了,直接改成如下代码,问题解决。

        $result = tap($this->user()->forceFill([
            **$attribute => $password,**
        ]))->save();

初次发文,请多关照!

longren610
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 6

Laravel多少版本有这个功能?

1周前 评论
longren610 (楼主) 1周前
ALMAS

话说入库时怎么会再hash一次?是不是自己写了修改器?

1周前 评论
longren610 (楼主) 1周前
ALMAS (作者) 1周前
longren610 (楼主) 1周前

直接改源码有点不妥吧,可以复写这个方法吗?

1周前 评论
longren610 (楼主) 1周前
BradStevens (作者) 1周前
longren610 (楼主) 6天前
BradStevens (作者) 6天前
Epona

此方法要求用户提供其当前密码,你的应用程序应通过输入表单接受该密码:

应该把未加密的密码传进去吧

1周前 评论
longren610 (楼主) 1周前

**这是什么语法

[
          **$attribute => Hash::make($password),** 
        ]
6天前 评论
longren610

@lovecn 前后的**号,只是想做一个提示,不是语法。。。 :joy:

6天前 评论

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!