关于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的主框架代码文件在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
);
}
|
1
|
$this
->session->put(
$this
->getName(),
$id
);
|
如果$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'
);
}
|
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信息,之后再尝试登录操作。