zoukankan      html  css  js  c++  java
  • 关于laravel框架的Auth::attempt验证失败

    按照官方文档进行认证 发现不管怎么样都是失败

    if (Auth::attempt(array('email' => $email, 'password' => $password), true))
    {
        // 用户状态永久保存...
    }
    

    研究他的源代码 Auth定义在 vendor/laravel/framework/src/Illuminate/Auth 

    attempt方法在Guard.php 这个方法最关键的就是 $this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials); 这一句

    $credentials就是我们上面传进来的数组了 此时var_dump($user) 这个变量是正确 有值的 所以也就是if ($this->provider->validateCredentials($user, $credentials)) 这句验证没通过

    $provider 这个属性的定义

        /**
         * The user provider implementation.
         *
         * @var IlluminateAuthUserProviderInterface
         */
        protected $provider;
    UserProviderInterface 是一个抽象类
    联系到 config/auth.php 中 driver 项有 Supported: "database", "eloquent" 所以 DatabaseUserProvider 或 EloquentUserProvider就是具体的实现了
    validateCredentials 方法定义
    	/**
    	 * Validate a user against the given credentials.
    	 *
    	 * @param  IlluminateAuthUserInterface  $user
    	 * @param  array  $credentials
    	 * @return bool
    	 */
    	public function validateCredentials(UserInterface $user, array $credentials)
    	{
    		$plain = $credentials['password'];
    
    		return $this->hasher->check($plain, $user->getAuthPassword());
    	}
    
    
    

    $hasher 在 IlluminateHashingHasherInterface

    官方文档有这一句 The Laravel Hash class provides secure Bcrypt hashing: 也就是 BcryptHasher类的check方法

    	/**
    	 * Check the given plain value against a hash.
    	 *
    	 * @param  string  $value
    	 * @param  string  $hashedValue
    	 * @param  array   $options
    	 * @return bool
    	 */
    	public function check($value, $hashedValue, array $options = array())
    	{
    		return password_verify($value, $hashedValue);
    	}
    

    用的是password_verify 跟我们常用的md5什么的完全不搭 难怪失败  

    找到原因但在官方文档没找到解决的方法 无奈用 auth attempt md5  password hash等关键字google 才发现其实是有文档的  可见细心是多么重要

    http://laravel.com/docs/extending#authentication

    接着自己新建一个类 class HeyliUserProvider implements UserProviderInterface  密码验证方法validateCredentials就可以完全按照自己的业务逻辑了

    Auth::extend('heyli',function($appextend的第一个参数也就是验证方式的名称了 把 config/auth.php中的driver变成相对应的就可以了

    PS:当你用户表主键不是 ID或密码字段不是password 的时候就会出错了  return new GenericUser((array) $user);   GenericUser类有下面方法

        /**
         * Get the unique identifier for the user.
         *
         * @return mixed
         */
        public function getAuthIdentifier()
        {
            return $this->attributes['id'];
        }
    
        /**
         * Get the password for the user.
         *
         * @return string
         */
        public function getAuthPassword()
        {
            return $this->attributes['password'];
        }

    此时在HeyliUserProvider 这个类中的 retrieveById retrieveByCredentials 这两个方法 添加 

    if ( ! is_null($user))
    {
    $user->id = (string) $user->uid;  //添加这一句 像我的主键是UID  
    return new GenericUser((array) $user);
    }

    最后记得在 app/start/global.php 添加上

    Auth::extend('heyli', function($app) {
        $provider =  new ExampleAuthHeyliUserProvider();
    
        return new IlluminateAuthGuard($provider, App::make('session.store'));
    });
    我编了个故事把自己骗了
  • 相关阅读:
    Kubernetes 无法删除pod实例的排查过程
    kubeadm 生成的token过期后,集群增加节点
    linux 常规操作EOF写法梳理
    linux下EOF写法梳理
    容器云之弹性伸缩
    QEMU,KVM及QEMU-KVM介绍
    听听八年阿里架构师怎样讲述Dubbo和Spring Cloud微服务架构
    代码内存泄露检测(1) MLeaksFinder (Wechat开源) + FBRetainCycleDetector (FaceBook开源)
    Xcode 创建使用多个 target (1)
    iOS 多线程的简单理解(4) 线程锁的简单使用
  • 原文地址:https://www.cnblogs.com/heyli/p/3572708.html
Copyright © 2011-2022 走看看