欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

Laravel 使用Auth登录验证

shiping1 的头像
昨天在继续自己la-cms的过程中,又遇到了一个蛋疼问题。

当按照一切配置好路由,配置后,每次运行都报错,改来改去还是报各种错。

今天上午在研究Laravel关于Auth类验证的过程。

关于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信息保留了。

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

 

// 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); 
		}

 

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

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

 

$_SESSION = NULL ;
$_COOKIE = NULL ;

 

好了,关于laravel也是很多东西要去研究。

后台编辑器重新定义了新插件,随后会写文章讲述过程。

 

普通分类: