Laravel 使用Auth登录验证

关于Auth类的简单介绍和使用参见文档:http://v4.golaravel.com/docs/4.0/security

跟着文档走,我们先需要对配置项进行修改:" app/config/auth.php " 

1
2
3
4
5
6
7
8
9
10
return array (
     'driver' => 'eloquent' ,
     'model' => 'User' ,
     'table' => 'user' ,
     'reminder' => array (
         'email' => 'emails.auth.reminder' ,
         'table' => 'password_reminders' ,
         'expire' => 60,
     ),
);

这里定义了一个驱动器,一个进行验证的类User,这个类位于应用目录app/models下,同样的定义了一个用户表,这里要改成自己项目中的对应的表。

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

1
$password = Hash::make( 'secret' );

接下来我们创建一个登录的路由,路由分为GET和POST请求两个。

1
2
Route::get( 'login' , 'UserController@loginGet' );
Route::post( 'login' , 'UserController@loginPost' );

我们去创建User控制器,并且完善loginGet和loginPost方法。

1
2
3
4
public function loginGet()
{
     return View::make( 'user.login' );
}
验证登录方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
     * 验证登录
     */
     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类中,需要实现验证接口。

1
2
3
4
5
6
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
 
class User extends Eloquent implements UserInterface,RemindableInterface{
    //pass
}

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

1
2
3
4
5
6
7
8
9
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文件中的类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
      * 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控制。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/**
      * 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。
1
$this ->session->put( $this ->getName(), $id );
这里将有关信息放入session.

如果$remember为true就会执行这个代码块:

1
2
3
4
5
6
if ( $remember )
{
     $this ->createRememberTokenIfDoesntExist( $user );
 
     $this ->queueRecallerCookie( $user );
}

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

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

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

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

1
$this ->setUser( $user );

退出登录的方法:


1
2
3
4
5
6
7
8
9
/*
     *  退出登录
     */
     public function logout(){ 
         if (Auth::check()){
             Auth::logout();
         }
         return Redirect::to( 'login' );
     }


Auth的check( )方法:



1
2
3
4
5
6
7
8
9
/**
      * Determine if the current user is authenticated.
      *
      * @return bool
      */
     public function check()
     {
         return ! is_null ( $this ->user());
     }


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

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/**
      * 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信息保留了。

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


1
2
3
4
5
6
7
8
9
// 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信息,之后再尝试登录操作。

猜你喜欢

转载自blog.csdn.net/zj328316760/article/details/79931297