Files
yii2/docs/guide/security-authentication.md
cuiliang cd9caf65d2 20160611
2016-06-11 19:49:57 +08:00

14 KiB
Raw Blame History

Authentication

<<<<<<< HEAD <<<<<<< HEAD

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.

master

Yii provides an authentication framework which wires up various components to support login. To use this framework, you mainly need to do the following work:

Configuring yii\web\User

The yii\web\User application component manages the user authentication status. It requires you to specify an yii\web\User::identityClass which contains the actual authentication logic. In the following application configuration, the yii\web\User::identityClass for yii\web\User is configured to be app\models\User whose implementation is explained in the next subsection:

return [
    'components' => [
        'user' => [
            'identityClass' => 'app\models\User',
        ],
    ],
];

Implementing yii\web\IdentityInterface

The yii\web\User::identityClass must implement the yii\web\IdentityInterface which contains the following methods:

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() and yii\web\IdentityInterface::getId() while leaving all other methods with an empty body.

In the following example, an yii\web\User::identityClass is implemented as an Active Record class associated with the user database table.

<?php

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

class User extends ActiveRecord implements IdentityInterface
{
<<<<<<< HEAD
    // ...
=======
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.

Yii provides an authentication framework which wires up various components to support login. To use this framework, 
you mainly need to do the following work:
 
* Configure the [[yii\web\User|user]] application component;
* Create a class that implements the [[yii\web\IdentityInterface]] interface.


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

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 [
    'components' => [
        'user' => [
            'identityClass' => 'app\models\User',
        ],
    ],
];

Implementing yii\web\IdentityInterface

The yii\web\User::identityClass must implement the yii\web\IdentityInterface which contains the following methods:

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() and yii\web\IdentityInterface::getId() while leaving all other methods with an empty body.

In the following example, an yii\web\User::identityClass is implemented as an Active Record class associated with the user database table.

<?php

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

class User extends ActiveRecord implements IdentityInterface
{
=======
>>>>>>> master
    public static function tableName()
    {
        return 'user';
    }
<<<<<<< HEAD
>>>>>>> yiichina/master
=======
>>>>>>> master

    /**
     * Finds an identity by the given ID.
     *
     * @param string|integer $id the ID to be looked for
     * @return IdentityInterface|null the identity object that matches the given ID.
     */
    public static function findIdentity($id)
    {
        return static::findOne($id);
    }

    /**
     * Finds an identity by the given token.
     *
     * @param string $token the token to be looked for
     * @return IdentityInterface|null the identity object that matches the given token.
     */
    public static function findIdentityByAccessToken($token, $type = null)
    {
        return static::findOne(['access_token' => $token]);
    }

    /**
     * @return int|string current user ID
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @return string current user auth key
     */
    public function getAuthKey()
    {
        return $this->auth_key;
    }

    /**
     * @param string $authKey
     * @return boolean if auth key is valid for current user
     */
    public function validateAuthKey($authKey)
    {
        return $this->getAuthKey() === $authKey;
    }
}

<<<<<<< HEAD <<<<<<< HEAD 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:

master

class User extends ActiveRecord implements IdentityInterface
{
    ......
    
    public function beforeSave($insert)
    {
        if (parent::beforeSave($insert)) {
            if ($this->isNewRecord) {
                $this->auth_key = \Yii::$app->security->generateRandomString();
            }
            return true;
        }
        return false;
    }
}

<<<<<<< HEAD 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.

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:

class User extends ActiveRecord implements IdentityInterface
{
    ......
    
    public function beforeSave($insert)
    {
        if (parent::beforeSave($insert)) {
            if ($this->isNewRecord) {
                $this->auth_key = \Yii::$app->security->generateRandomString();
            }
            return true;
        }
        return false;
    }
}

=======

master 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 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

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 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:

// 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:

// 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 to the yii\web\User. If session is yii\web\User::enableSession, 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, 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

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

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

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, you may record the login time and IP address in the user table. <<<<<<< HEAD

yiichina/master ======= master