欢迎来到无限飞翔,在这里,你会找到许多有趣的技术 : )

Laravel 使用Auth登录验证

PHP编程 lbbniu 529℃
原文地址:http://changziming.com/post-167.html
关于Auth类的简单介绍和使用参见文档:http://v4.golaravel.com/docs/4.0/security跟着文档走,我们先需要对配置项进行修改:” app/config/auth.php ”

return array(
    'driver' => 'eloquent',
    'model' => 'User',
    'table' => 'user',
    'reminder' => array(
        'email' => 'emails.auth.reminder',
        'table' => 'password_reminders',
        'expire' => 60,
    ),
);
这里定义了一个驱动器,一个进行验证的类User,这个类位于应用目录app/models下,同样的定义了一个用户表,这里要改成自己项目中的对应的表。

再往下看,Laravel中使用了Hash类来创建密码,具体用法如下:

$password = Hash::make('secret');
接下来我们创建一个登录的路由,路由分为GET和POST请求两个。
Route::get('login', 'UserController@loginGet');
Route::post('login', 'UserController@loginPost');
我们去创建User控制器,并且完善loginGet和loginPost方法。
public function loginGet()
{
    return View::make('user.login');
}
验证登录方法:
/*
    * 验证登录
    */
    public function loginPost(){
        $username = Input::get('name') ; 
        $password = Input::get('password') ; 
 
        if (Auth::attempt(array('username' => $username, 'password' => $password),false))
        {
            return Redirect::to('admin');  
 
        }else{
            return Redirect::to('login')->with('login_errors','用户名或密码不正确!');  
        } 
    }

接下来我这边就是各种错误。根据错误提示一条条修改。发现在User类中,需要实现验证接口。

use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
 
class User extends Eloquent implements UserInterface,RemindableInterface{
   //pass
}

然后要去重写接口中定义过的方法:

public function getRememberToken(){
        return $this->rememberToken ;
}
public function setRememberToken($value){ 
    $this->rememberToken = $value ; 
}
public function getRememberTokenName(){
    return $this->reminder ;
}

调试的过程中,发现中文文档给出的只言片语还是不足以去解决问题的,无奈打开Laravel的源码,开始一点一点理解。laravel的主框架代码文件在vendor\laravel\framework\src\Illuminate目录下。

关于Atuh模块在对应的Auth目录下。

我们使用的Auth类其实也就是Guard.php文件中的类。

/**
     * Attempt to authenticate a user using the given credentials.
     *
     * @param  array  $credentials
     * @param  bool   $remember
     * @param  bool   $login
     * @return bool
     */
    public function attempt(array $credentials = array(), $remember = false, $login = true)
    { 
        $this->fireAttemptEvent($credentials, $remember, $login);
 
        $user = $this->provider->retrieveByCredentials($credentials);
        // If an implementation of UserInterface was returned, we'll ask the provider
        // to validate the user against the given credentials, and if they are in
        // fact valid we'll log the users into the application and return true.
        if ($user instanceof UserInterface)
        { 
            if ($this->provider->validateCredentials($user, $credentials))
            {  
                if ($login) $this->login($user, $remember);
 
                return true;
            }
        }
 
        return false;
    }

这是验证用户名和密码并登录的方法,看出来需要array $credentials = array()这个条件参数,$remember是否记住登录。

如果$remember=true后,会在cookie中保存用户的一些信息。当用户的session清除之后,程序会继续尝试从cookie中的一些加密信息中把用户“恢复”出来。一般来说,使用默认值false就行了,不然还需要其他地方的一些调整。

这里的提供者$this->provider经验证是在Auth目录下的EloquentUserProvider.php文件中。

EloquentUserProvider类实现了接口UserProviderInterface,重写了接口中的方法,这个类主要是负责验证用户,定义一些token,和根据条件恢复用户。

只有$this->provider->validateCredentials($user, $credentials) 验证用户名和密码成功之后,才会调用$this->login($user, $remember)进行关于用户的session控制。

/**
     * Log a user into the application.
     *
     * @param  \Illuminate\Auth\UserInterface  $user
     * @param  bool  $remember
     * @return void
     */
    public function login(UserInterface $user, $remember = false)
    { 
        $id = $user->getAuthIdentifier();
 
        $this->session->put($this->getName(), $id);
 
        // If the user should be permanently "remembered" by the application we will
        // queue a permanent cookie that contains the encrypted copy of the user
        // identifier. We will then decrypt this later to retrieve the users.
        if ($remember)
        {
            $this->createRememberTokenIfDoesntExist($user);
 
            $this->queueRecallerCookie($user);
        }
 
        // If we have an event dispatcher instance set we will fire an event so that
        // any listeners will hook into the authentication events and run actions
        // based on the login and logout events fired from the guard instances.
        if (isset($this->events))
        {
            $this->events->fire('auth.login', array($user, $remember));
        }
 
        $this->setUser($user);
    }

这是登录的方法,先是获取用户表的主键ID,$id。

$this->session->put($this->getName(), $id);

这里将有关信息放入session.如果$remember为true就会执行这个代码块:

if ($remember)
{
    $this->createRememberTokenIfDoesntExist($user);
 
    $this->queueRecallerCookie($user);
}

看到这里会有关于cookie的相关操作,会将登录用户信息放入cookie中,方便“恢复”。

如果在登录后有监听的事件,会在这里执行:

if (isset($this->events))
{
    $this->events->fire('auth.login', array($user, $remember));
}

一切就绪,设置user,设置之后便可以在以后的流程中使用Auth类验证是否登录了。

$this->setUser($user);

退出登录的方法:

/*
    *  退出登录
    */
    public function logout(){  
        if(Auth::check()){ 
            Auth::logout();
        } 
        return Redirect::to('login'); 
    }

Auth的check( )方法:

/**
     * Determine if the current user is authenticated.
     *
     * @return bool
     */
    public function check()
    {
        return ! is_null($this->user());
    }

这里是user就是刚刚登录成功后设置的user。

通过user()获取user信息的方法:

/**
     * Get the currently authenticated user.
     *
     * @return \Illuminate\Auth\UserInterface|null
     */
    public function user()
    {    
        if ($this->loggedOut) return;
 
        // If we have already retrieved the user for the current request we can just
        // return it back immediately. We do not want to pull the user data every
        // request into the method becaue that would tremendously slow the app.
        if ( ! is_null($this->user))
        {
            return $this->user;
        }
 
        $id = $this->session->get($this->getName());
 
        // First we will try to load the user using the identifier in the session if
        // one exists. Otherwise we will check for a "remember me" cookie in this
        // request, and if one exists, attempt to retrieve the user using that.
        $user = null;
 
        if ( ! is_null($id))
        {
            $user = $this->provider->retrieveByID($id);
        }
 
        // If the user is null, but we decrypt a "recaller" cookie we can attempt to
        // pull the user data on that cookie which serves as a remember cookie on
        // the application. Once we have a user we can return it to the caller.
        $recaller = $this->getRecaller();
 
        if (is_null($user) and ! is_null($recaller))
        {   
            $user = $this->getUserByRecaller($recaller); 
        }
 
 
        return $this->user = $user;
    }

如果用户登录时$rember为true,退出登录时候出错,SESSION信息清除,COOKIE信息保留了。

再进行验证就会出错,原因在与:

这里会尝试根据cookie中的信息进行“恢复”用户。

我是执行这样,先清除本机的cookie信息,之后再尝试登录操作。

$_SESSION = NULL ;
$_COOKIE = NULL ;

转载请注明:无限飞翔 » Laravel 使用Auth登录验证

喜欢 (151)or分享 (0)