Skip to content

Commit

Permalink
finished auth guide [skip ci]
Browse files Browse the repository at this point in the history
  • Loading branch information
qiangxue committed Apr 24, 2015
1 parent 74481d8 commit a9ac83b
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 29 deletions.
137 changes: 109 additions & 28 deletions docs/guide/security-authentication.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
Authentication
==============

> Note: This section is under development.
Authentication is the process of verifying the identity of a user. It usually uses an identifier
(e.g. a username or an email address) and a secret token (e.g. a password or an access token) to judge
if the user is the one whom he claims as. Authentication is the basis of the login feature.
Expand All @@ -16,10 +14,11 @@ you mainly need to do the following work:

## Configuring [[yii\web\User]] <span id="configuring-user"></span>

The [[yii\web\User|user]] application component manages the user authentication status. With the help of
an [[yii\web\User::identityClass|identity class]], it implements the full login workflow. In the following
application configuration, the [[yii\web\User::identityClass|identity class]] for [[yii\web\User|user]]
is configured to be `app\models\User` whose implementation is explained in the next subsection:
The [[yii\web\User|user]] application component manages the user authentication status. It requires you to
specify an [[yii\web\User::identityClass|identity class]] which contains the actual authentication logic.
In the following application configuration, the [[yii\web\User::identityClass|identity class]] for
[[yii\web\User|user]] is configured to be `app\models\User` whose implementation is explained in
the next subsection:

```php
return [
Expand All @@ -34,8 +33,8 @@ return [

## Implementing [[yii\web\IdentityInterface]] <span id="implementing-identity"></span>

The [[yii\web\User::identityClass|identity class]] must implement the [[yii\web\IdentityInterface]] which
requires the implementation of the following methods:
The [[yii\web\User::identityClass|identity class]] must implement the [[yii\web\IdentityInterface]] contains
the following methods:

* [[yii\web\IdentityInterface::findIdentity()|findIdentity()]]: it looks for an instance of the identity
class using the specified user ID. This method is used when you need to maintain logic status via session.
Expand All @@ -49,19 +48,25 @@ requires the implementation of the following methods:
* [[yii\web\IdentityInterface::validateAuthKey()|validateAuthKey()]]: it implements the logic for verifying
the cookie-based login key.

As you can see, these methods are required by different features. If you do not need a particular feature,
you may implement the corresponding methods with an empty body. For example, if your application is a pure
stateless RESTful application, you would only need to implement [[yii\web\IdentityInterface::findIdentityByAccessToken()|findIdentityByAccessToken()]]
and [[yii\web\IdentityInterface::getId()|getId()]].

If a particular method is not needed, you may implement it with an empty body. For example, if your application
is a pure stateless RESTful application, you would only need to implement [[yii\web\IdentityInterface::findIdentityByAccessToken()|findIdentityByAccessToken()]]
and [[yii\web\IdentityInterface::getId()|getId()]] while leaving all other methods with an empty body.

You can find a fully featured example of authentication in the
[advanced project template](https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/README.md). Below, only the interface methods are listed:
In the following example, an [[yii\web\User::identityClass|identity class]] is implemented as
an [Active Record](db-active-record.md) class associated with the `user` database table.

```php
<?php

use yii\db\ActiveRecord;
use yii\web\IdentityInterface;

class User extends ActiveRecord implements IdentityInterface
{
// ...
public static function tableName()
{
return 'user';
}

/**
* Finds an identity by the given ID.
Expand Down Expand Up @@ -112,23 +117,99 @@ class User extends ActiveRecord implements IdentityInterface
}
```

Two of the outlined methods are simple: `findIdentity` is provided with an ID value and returns a model instance
associated with that ID. The `getId` method returns the ID itself. Two of the other methods – `getAuthKey` and
`validateAuthKey` – are used to provide extra security to the "remember me" cookie. The `getAuthKey` method should
return a string that is unique for each user. You can reliably create a unique string using
`Yii::$app->getSecurity()->generateRandomString()`. It's a good idea to also save this as part of the user's record:
As explained previously, you only need to implement `getAuthKey()` and `validateAuthKey()` if your application
uses cookie-based login feature. In this case, you may use the following code to generate an auth key for each
user and store it in the `user` table:

```php
public function beforeSave($insert)
class User extends ActiveRecord implements IdentityInterface
{
if (parent::beforeSave($insert)) {
if ($this->isNewRecord) {
$this->auth_key = Yii::$app->getSecurity()->generateRandomString();
......

public function beforeSave($insert)
{
if (parent::beforeSave($insert)) {
if ($this->isNewRecord) {
$this->auth_key = \Yii::$app->security->generateRandomString();
}
return true;
}
return true;
return false;
}
return false;
}
```

The `validateAuthKey` method just needs to compare the `$authKey` variable, passed as a parameter (itself retrieved from a cookie), with the value fetched from the database.
> Note: Do not confuse the `User` identity class with [[yii\web\User]]. The former is the class implementing
the authentication logic. It is often implemented as an [Active Record](db-active-record.md) class associated
with some persistent storage for storing the user credential information. The latter is an application component
class responsible for managing the user authentication state.


## Using [[yii\web\User]] <span id="using-user"></span>

You mainly use [[yii\web\User]] in terms of the `user` application component.

You can detect the identity of the current user using the expression `Yii::$app->user->identity`. It returns
an instance of the [[yii\web\User::identityClass|identity class]] representing the currently logged-in user,
or null if the current user is not authenticated (meaning a guest). The following code shows how to retrieve
other authentication-related information from [[yii\web\User]]:

```php
// the current user identity. Null if the user is not authenticated.
$identity = Yii::$app->user->identity;

// the ID of the current user. Null if the user not authenticated.
$id = Yii::$app->user->id;

// whether the current user is a guest (not authenticated)
$isGuest = Yii::$app->user->isGuest;
```

To login a user, you may use the following code:

```php
// find a user identity with the specified username.
// note that you may want to check the password if needed
$identity = User::findOne(['username' => $username]);

// logs in the user
Yii::$app->user->login($identity);
```

The [[yii\web\User::login()]] method sets the identity of the current user. If session is
[[yii\web\User::enableSession|enabled]], it will keep the identity in the session so that the user
authentication status is maintained throughout the whole session. If cookie-based login (i.e. "remember me" login)
is [[yii\web\User::enableAutoLogin|enabled]], it will also save the identity in a cookie so that
the user authentication status can be recovered from the cookie as long as the cookie remains valid.

In order to enable cookie-based login, you need to configure [[yii\web\User::enableAutoLogin]] to be
true in the application configuration. You also need to provide a duration time parameter when calling
the [[yii\web\User::login()]] method.

To logout a user, simply call

```php
Yii::$app->user->logout();
```

Note that logging out a user is only meaningful when session is enabled. The method will clean up
the user authentication status from both memory and session. And by default, it will also destroy *all*
user session data. If you want to keep the session data, you should call `Yii::$app->user->logout(false)`, instead.


## Authentication Events <span id="auth-events"></span>

The [[yii\web\User]] class raises a few events during the login and logout processes.

* [[yii\web\User::EVENT_BEFORE_LOGIN|EVENT_BEFORE_LOGIN]]: raised at the beginning of [[yii\web\User::login()]].
If the event handler sets the [[yii\web\UserEvent::isValid|isValid]] property of the event object to be false,
the login process will be cancelled.
* [[yii\web\User::EVENT_AFTER_LOGIN|EVENT_AFTER_LOGIN]]: raised after a successful login.
* [[yii\web\User::EVENT_BEFORE_LOGOUT|EVENT_BEFORE_LOGOUT]]: raised at the beginning of [[yii\web\User::logout()]].
If the event handler sets the [[yii\web\UserEvent::isValid|isValid]] property of the event object to be false,
the logout process will be cancelled.
* [[yii\web\User::EVENT_AFTER_LOGOUT|EVENT_AFTER_LOGOUT]]: raised after a successful logout.

You may respond to these events to implement features such as login audit, online user statistics. For example,
in the handler for [[yii\web\User::EVENT_AFTER_LOGIN|EVENT_AFTER_LOGIN]], you may record the login time and IP
address in the `user` table.
2 changes: 1 addition & 1 deletion docs/internals/translation-status.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ output-sorting.md | Yes
output-data-providers.md | Yes
output-data-widgets.md |
output-theming.md | Yes
security-authentication.md |
security-authentication.md | Yes
security-authorization.md |
security-passwords.md |
security-auth-clients.md |
Expand Down

0 comments on commit a9ac83b

Please sign in to comment.