根目录/modules/user模块
user.module ->user_menu ->'page callback' => 'user_page',
function user_page() {
global $user;
if ($user->uid) {
menu_set_active_item('user/' . $user->uid);
return menu_execute_active_handler(NULL, FALSE);
}
else {
return drupal_get_form('user_login');
}
}
未登录状态 调用 user_login
function user_login($form, &$form_state) {
global $user;
// If we are already logged on, go to the user page instead.
if ($user->uid) {
drupal_goto('user/' . $user->uid);
}
// Display login form:
$form['name'] = array('#type' => 'textfield',
'#title' => t('Username'),
'#size' => 60,
'#maxlength' => USERNAME_MAX_LENGTH,
'#required' => TRUE,
);
$form['name']['#description'] = t('Enter your @s username.', array('@s' => variable_get('site_name', 'Drupal')));
$form['pass'] = array('#type' => 'password',
'#title' => t('Password'),
'#description' => t('Enter the password that accompanies your username.'),
'#required' => TRUE,
);
$form['#validate'] = user_login_default_validators();
$form['actions'] = array('#type' => 'actions');
$form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Log in'));
return $form;
}
$form['#validate'] = user_login_default_validators(); 是判断用户名和密码的
function user_login_default_validators() {
return array('user_login_name_validate', 'user_login_authenticate_validate', 'user_login_final_validate');
}
function user_login_name_validate($form, &$form_state) {
if (!empty($form_state['values']['name']) && user_is_blocked($form_state['values']['name'])) {
// Blocked in user administration.
form_set_error('name', t('The username %name has not been activated or is blocked.', array('%name' => $form_state['values']['name'])));
}
}
function user_login_authenticate_validate($form, &$form_state) {
$password = trim($form_state['values']['pass']);
if (!empty($form_state['values']['name']) && strlen(trim($password)) > 0) {
// Do not allow any login from the current user's IP if the limit has been
// reached. Default is 50 failed attempts allowed in one hour. This is
// independent of the per-user limit to catch attempts from one IP to log
// in to many different user accounts. We have a reasonably high limit
// since there may be only one apparent IP for all users at an institution.
if (!flood_is_allowed('failed_login_attempt_ip', variable_get('user_failed_login_ip_limit', 50), variable_get('user_failed_login_ip_window', 3600))) {
$form_state['flood_control_triggered'] = 'ip';
return;
}
$account = db_query("SELECT * FROM {users} WHERE name = :name AND status = 1", array(':name' => $form_state['values']['name']))->fetchObject();
if ($account) {
if (variable_get('user_failed_login_identifier_uid_only', FALSE)) {
// Register flood events based on the uid only, so they apply for any
// IP address. This is the most secure option.
$identifier = $account->uid;
}
else {
// The default identifier is a combination of uid and IP address. This
// is less secure but more resistant to denial-of-service attacks that
// could lock out all users with public user names.
$identifier = $account->uid . '-' . ip_address();
}
$form_state['flood_control_user_identifier'] = $identifier;
// Don't allow login if the limit for this user has been reached.
// Default is to allow 5 failed attempts every 6 hours.
if (!flood_is_allowed('failed_login_attempt_user', variable_get('user_failed_login_user_limit', 5), variable_get('user_failed_login_user_window', 21600), $identifier)) {
$form_state['flood_control_triggered'] = 'user';
return;
}
}
// We are not limited by flood control, so try to aut
function user_authenticate($name, $password) {
$uid = FALSE;
if (!empty($name) && strlen(trim($password)) > 0) {
$account = user_load_by_name($name);
if ($account) {
// Allow alternate password hashing schemes.
require_once DRUPAL_ROOT . '/' . variable_get('password_inc', 'includes/password.inc');
if (user_check_password($password, $account)) {
// Successful authentication.
$uid = $account->uid;
// Update user to new password scheme if needed.
if (user_needs_new_hash($account)) {
user_save($account, array('pass' => $password));
}
}
}
}
return $uid;
}
function user_check_password($password, $account) {
if (substr($account->pass, 0, 2) == 'U$') {
// This may be an updated password from user_update_7000(). Such hashes
// have 'U' added as the first character and need an extra md5().
$stored_hash = substr($account->pass, 1);
$password = md5($password);
}
else {
$stored_hash = $account->pass;
}
$type = substr($stored_hash, 0, 3);
switch ($type) {
case '$S$':
// A normal Drupal 7 password using sha512.
$hash = _password_crypt('sha512', $password, $stored_hash);
break;
case '$H$':
// phpBB3 uses "$H$" for the same thing as "$P$".
case '$P$':
// A phpass password generated using md5. This is an
// imported password or from an earlier Drupal version.
$hash = _password_crypt('md5', $password, $stored_hash);
break;
default:
return FALSE;
}
return ($hash && $stored_hash == $hash);
}