I've installed the Email Registration module because I want my site's users to be able to register an account, and use their email address as their login username. This works great on the web login, however I've built an app to log users into my Drupal site as well using the Services module. When I try and log users in with their email address username, access is denied (whereas when they log in via the website, it authenticates just fine). Any idea why this might be?
1 Answer
The Email Registration module doesn't create any service resource. Also it doesn't change user login resource of the Services module that allows users to login just with their names. I have implemented user email and name login solution with this custom service:
/**
* Implements hook_services_resources().
*/
function custom_mail_login_services_resources() {
return array(
'custom_email_login' => array(
'actions'=>array (
'mail_login' => array(
'callback' => 'get_mail_login',
'access callback' => 'user_is_anonymous',
'args' => array(
array(
'name' => 'data',
'optional' => FALSE,
'source' => 'data',
'type' => 'array',
'description' => 'Name or email',
),
),
),
),
),
);
}
function get_mail_login($data) {
global $user;
$username = null;
if ($name = db_query('SELECT name FROM {users} WHERE LOWER(mail) = LOWER(:mail)', array(':mail' => $data['mail']))->fetchField()) {
$username = $name;
}elseif ($name = db_query('SELECT name FROM {users} WHERE LOWER(name) = LOWER(:name)', array(':name' => $data['mail']))->fetchField()) {
$username = $name;
}else{
return services_error(t('No user with this email or name exists!'), 403);
}
if ($user->uid) {
// user is already logged in
return services_error(t('Already logged in as @user.', array('@user' => $user->mail)), 406);
}
// Check if account is active.
if (user_is_blocked($username)) {
return services_error(t('The user %name has not been activated or is blocked.', array('%name' => $mail)), 403);
}
// Emulate drupal native flood control: check for flood condition.
$flood_state = array();
if (variable_get('services_flood_control_enabled', TRUE)) {
$flood_state = _user_resource_flood_control_precheck($username);
}
// Only authenticate if a flood condition was not detected.
if (empty($flood_state['flood_control_triggered'])) {
$uid = user_authenticate($username, $data['password']);
}
else {
$uid = FALSE;
}
// Emulate drupal native flood control: register flood event, and throw error
// if a flood condition was previously detected
if (variable_get('services_flood_control_enabled', TRUE)) {
$flood_state['uid'] = $uid;
_user_resource_flood_control_postcheck($flood_state);
}
if ($uid) {
$user = user_load($uid);
if ($user->uid) {
user_login_finalize();
$return = new stdClass();
$return->sessid = session_id();
$return->session_name = session_name();
$return->token = drupal_get_token('services');
$account = clone $user;
services_remove_user_data($account);
$return->user = $account;
return $return;
}
}
watchdog('user', 'Invalid login attempt for %username.', array('%username' => $username));
return services_error(t('Wrong username/email or password.'), 401);
}
You have to put this code into your custom_mail_login.module file and add custom_mail_login. info file. Module name is custom_mail_login. Then enable this module and custom_email_login mail_login resource in admin/structure/services/list/your_endpoint/resources.
You have to send json request {"mail":"[email protected]", "password":"password"}
. The parameter "mail" is an email or user name.