<commit_before>Authentication and Authorization
================================

Authentication and authorization are required for a Web page that should
be limited to certain users. *Authentication* is about verifying whether
someone is who they claim to be. It usually involves a username and a
password, but may include any other methods of demonstrating identity, such
as a smart card, fingerprints, etc. *Authorization* is finding out if the
person, once identified (i.e. authenticated), is permitted to manipulate
specific resources. This is usually determined by finding out if that
person is of a particular role that has access to the resources.

Yii has a built-in authentication/authorization (auth) framework which is
easy to use and can be customized for special needs.

The central piece in the Yii auth framework is a pre-declared *user
application component* which is an object implementing the [IWebUser]
interface. The user component represents the persistent identity
information for the current user. We can access it at any place using
`Yii::app()->user`.

Using the user component, we can check if a user is logged in or not via
[CWebUser::isGuest]; we can [login|CWebUser::login] and
[logout|CWebUser::logout] a user; we can check if the user can perform
specific operations by calling [CWebUser::checkAccess]; and we can also
obtain the [unique identifier|CWebUser::name] and other persistent identity
information about the user.

Defining Identity Class
-----------------------

As mentioned above, authentication is about validating the identity of the user. A typical Web application authentication implementation usually involves using a username and password combination to verify a user's identity. However, it may include other methods and different implementations may be required. To accommodate varying authentication methods, the Yii auth framework introduces the identity class.

We define an identity class which contains the actual authentication logic. The identity class should implement the [IUserIdentity] interface. Different identity classes can be
implemented for different authentication approaches (e.g. OpenID, LDAP, Twitter OAuth, Facebook Connect). A good start when writing your own implementation is to extend [CUserIdentity] which is a base class for the authentication approach using a username and password.

The main work in defining an identity class is the implementation of the
[IUserIdentity::authenticate] method. This is the method used to encapsulate the main details of the authentication approach. An identity class may also declare
additional identity information that needs to be persistent during the user
session.

#### An Example

In the following example, we use an identity class to demonstrate using a database approach to authentication. This is very typical of most Web applications. A user will enter their username and password into a login form, and then we validate these credentials, using [ActiveRecord](/doc/guide/database.ar), against a user table in the database . There are actually a few things being demonstrated in this single example:

1. The implementation of the `authenticate()` method to use the database to validate credentials.
2. Overriding the `CUserIdentity::getId()` method to return the `_id` property because the default implementation returns the username as the ID.
3. Using the `setState()` ([CBaseUserIdentity::setState]) method to demonstrate storing other information that can easily be retrieved upon subsequent requests.

~~~
[php]
class UserIdentity extends CUserIdentity
{
	private $_id;
	public function authenticate()
	{
		$record=User::model()->findByAttributes(array('username'=>$this->username));
		if($record===null)
			$this->errorCode=self::ERROR_USERNAME_INVALID;
		else if($record->password!==md5($this->password))
			$this->errorCode=self::ERROR_PASSWORD_INVALID;
		else
		{
			$this->_id=$record->id;
			$this->setState('title', $record->title);
			$this->errorCode=self::ERROR_NONE;
		}
		return !$this->errorCode;
    }

	public function getId()
	{
		return $this->_id;
	}
}
~~~

When we cover login and logout in the next section, we'll see that we pass this identity class into the login method for a user. Any information that we store in a state (by calling [CBaseUserIdentity::setState]) will be passed to [CWebUser], which in turn will store them in a persistent storage, such as session.
This information can then be accessed like properties of [CWebUser]. In our example, we stored the user title information via `$this->setState('title', $record->title);`. Once we complete our login process, we can obtain the `title` information of the current user by simply using `Yii::app()->user->title`.

> Info: By default, [CWebUser] uses session as persistent storage for user
identity information. If cookie-based login is enabled (by setting
[CWebUser::allowAutoLogin] to be true), the user identity information may
also be saved in cookie. Make sure you do not declare sensitive information
(e.g. password) to be persistent.
<commit_msg>Proposed changes to Auth topic of the Guide to remove use of md5()<commit_after>Authentication and Authorization
================================

Authentication and authorization are required for a Web page that should
be limited to certain users. *Authentication* is about verifying whether
someone is who they claim to be. It usually involves a username and a
password, but may include any other methods of demonstrating identity, such
as a smart card, fingerprints, etc. *Authorization* is finding out if the
person, once identified (i.e. authenticated), is permitted to manipulate
specific resources. This is usually determined by finding out if that
person is of a particular role that has access to the resources.

Yii has a built-in authentication/authorization (auth) framework which is
easy to use and can be customized for special needs.

The central piece in the Yii auth framework is a pre-declared *user
application component* which is an object implementing the [IWebUser]
interface. The user component represents the persistent identity
information for the current user. We can access it at any place using
`Yii::app()->user`.

Using the user component, we can check if a user is logged in or not via
[CWebUser::isGuest]; we can [login|CWebUser::login] and
[logout|CWebUser::logout] a user; we can check if the user can perform
specific operations by calling [CWebUser::checkAccess]; and we can also
obtain the [unique identifier|CWebUser::name] and other persistent identity
information about the user.

Defining Identity Class
-----------------------

As mentioned above, authentication is about validating the identity of the user. A typical Web application authentication implementation usually involves using a username and password combination to verify a user's identity. However, it may include other methods and different implementations may be required. To accommodate varying authentication methods, the Yii auth framework introduces the identity class.

We define an identity class which contains the actual authentication logic. The identity class should implement the [IUserIdentity] interface. Different identity classes can be
implemented for different authentication approaches (e.g. OpenID, LDAP, Twitter OAuth, Facebook Connect). A good start when writing your own implementation is to extend [CUserIdentity] which is a base class for the authentication approach using a username and password.

The main work in defining an identity class is the implementation of the
[IUserIdentity::authenticate] method. This is the method used to encapsulate the main details of the authentication approach. An identity class may also declare
additional identity information that needs to be persistent during the user
session.

#### An Example

In the following example, we use an identity class to demonstrate using a database approach to authentication. This is typical in Web applications. A user will enter their username and password into a login form, and then we validate these credentials, using [ActiveRecord](/doc/guide/database.ar), against a user table in the database . There are actually a few things being demonstrated in this single example:

1. The implementation of the `authenticate()` method to use the database to validate credentials.
2. Overriding the `CUserIdentity::getId()` method to return the `_id` property because the default implementation returns the username as the ID.
3. Using the `setState()` ([CBaseUserIdentity::setState]) method to demonstrate storing other information that can easily be retrieved upon subsequent requests.

~~~
[php]
class UserIdentity extends CUserIdentity
{
	private $_id;
	public function authenticate()
	{
		$record=User::model()->findByAttributes(array('username'=>$this->username));
		if($record===null)
			$this->errorCode=self::ERROR_USERNAME_INVALID;
		else if($record->password!==crypt($this->password,$record->password))
			$this->errorCode=self::ERROR_PASSWORD_INVALID;
		else
		{
			$this->_id=$record->id;
			$this->setState('title', $record->title);
			$this->errorCode=self::ERROR_NONE;
		}
		return !$this->errorCode;
    }

	public function getId()
	{
		return $this->_id;
	}
}
~~~

When we cover login and logout in the next section, we'll see that we pass this identity class into the login method for a user. Any information that we store in a state (by calling [CBaseUserIdentity::setState]) will be passed to [CWebUser], which in turn will store them in a persistent storage, such as session.
This information can then be accessed like properties of [CWebUser]. In our example, we stored the user title information via `$this->setState('title', $record->title);`. Once we complete our login process, we can obtain the `title` information of the current user by simply using `Yii::app()->user->title`.

> Info: By default, [CWebUser] uses session as persistent storage for user
identity information. If cookie-based login is enabled (by setting
[CWebUser::allowAutoLogin] to be true), the user identity information may
also be saved in cookie. Make sure you do not declare sensitive information
(e.g. password) to be persistent.

> Tip: Secure storage of user passwords in a database requires some care. An attacker that has stolen your user table can recover passwords using standard techniques if you don't protect against them. In particular you should salt the password be fore hashing and use a hash function that is computationally expensive. The above code example uses the PHP `crypt()` function, [this README](https://github.com/tom--/Randomness/blob/master/README.mkd) has full details on how it works.

{'fraction_non_alphanumeric': 0.07469811850603764, 'fraction_numerical': 0.000748853318356267, 'mean_word_length': 5.077360637087599, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 45, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4409183', 'n_tokens_mistral': 2561, 'n_tokens_neox': 2469, 'n_words': 1411}