关于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, ), );
再往下看,Laravel中使用了Hash类来创建密码,具体用法如下:
$password = Hash::make('secret');
Route::get('login', 'UserController@loginGet'); Route::post('login', 'UserController@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登录验证