2

I can send out personalized links from CiviCRM, as described here. https://aghstrategies.com/content/how-create-one-click-personalized-links-civicrm-emails

They contain the contact id and a checksum that civicrm manages. Following the link will 'identify' the user.

Can I use such a link to have a contact that has a Drupal account log in to Drupal ?

I have a module in which I can create a menu router, validate the url, find a drupal id, log a user in, and redirect, I reckon. But to validate the url, I have to validate the checksum which afaik is not in the API, so I have to call the deep dark Core::BAODAO magic.

Is there an easy way to do this ?

If not, can someone sketch the BAODAO part ?

2

I was looking for a way to validate the checksum at one point, too. Here's what I found:

CRM_Contact_BAO_Contact_Utils::validChecksum($cid, $_GET["cs"])

which takes a CiviCRM contact id ($cid) and compares it to the checksum in the URL and did the trick for me.

UPDATE:

It looks like the usage has changed slightly in core since I pulled the above out of there (although the above was still working for me). Below was taken from here:

    //check if this is a checksum authentication
$userChecksum = CRM_Utils_Request::retrieve('cs', 'String', $this);
if ($userChecksum) {
  //check for anonymous user.
  $validUser = CRM_Contact_BAO_Contact_Utils::validChecksum($tempID, $userChecksum);
  if ($validUser) {
    return $tempID;
  }
}
  • Alsmost there. I can send a link with {contact.contact_id} and {contact.checksum} from a CiviCRM mail template. But if I validate it using CRM_Contact_BAO_Contact_Utils::validChecksum($cid, $checksum) it returns false. Am I .. expecting the wrong thing here ? – commonpike May 18 '15 at 13:47
  • @commonpike Try the updated code and let me know if that works for you. – Laryn - CEDC.org May 18 '15 at 14:34
  • Thanks, but I dont see much difference. $this is a form, which I dont have, but i guess it gets a checksum. $tempID is a contact ID. I think. – commonpike May 18 '15 at 14:53
  • Yes, $tempID is the contact ID. But taking a step back, I wonder if you can just use the function I pulled the code above from (ie. getContactID() ) and let CiviCRM do all the checking for you: github.com/civicrm/civicrm-core/blob/4.6/CRM/Core/… – Laryn - CEDC.org May 18 '15 at 15:22
  • 1
    To be precise, I used CRM_Contact_BAO_Contact_Utils::validChecksum($cid, $_GET["cs"]) – commonpike May 28 '15 at 11:53
1

CiviCRM intentionally doesn't provide login functionality for the CMS. Access bypass could have serious implications for your org - use with caution. You don't want to wake up in the newspaper because your membership DB got disclosed.

Similarly, CiviCRM emails aren't treated the same way that password reset emails are. People forward CiviCRM emails a lot, and if you're providing login functionality you risk exposing user information when doing so.

Use the examples below with care.


If you want to use CiviCRM checksums to implement the same functionality as a Drupal login, you could do the following perhaps?

  • Create a custom extension which provides a custom menu callback (eg civicrm/user-login).
  • In your custom callback, identify the Drupal user and log them in. (This is really easy.
  • Send out an email with a CiviCRM checksum pointed at this callback and perhaps with an additional parameter indicating the final destination URL.
  • Perhaps add some checks to prevent it working for any users with "administer site configuration" permissions to limit the chance of abuse.

You have code to validate a checksum above, so from here you'd want to -

Identify the user to match

$params = array(
  'version' => 3,
  'sequential' => 1,
  'contact_id' => 1,
);
$result = civicrm_api('UFMatch', 'get', $params);
// $uid is $result['values'][0]['uf_id'] or similar here.

Load the matching user

$account = user_load($uid);

Check they aren't an admin (fairly arbitrary this)

if (!user_access('administer site configuration', $account)) {
  // ...
}

Log them in

global $user;
$user = $account;

CiviCRM provides multiple concurrent checksums, since a user may have received one of several emails recently. Drupal provides only a single user login URL at a time.

It is possible to add Drupal login URLs to an email, and you could do this by implementing your own custom token, BUT you'd have to play along with Drupal's login lifespan (24 or 48H?) and any other limitations. CiviCRM checksums will be easier to handle here, provided you can account for the security implications of doing this :)

0

If you are really wanting to mail out a link that logs the user in, then it's not really a CiviCRM question, since authentication is handled by Drupal. Here are some modules that might help you:

  • They both sound interesting. However, i want to send the mailing using CiviCRM. Can I access these features from within the mailing modile ? – commonpike May 15 '15 at 13:17
  • Not sure, you'd have to dig into the apis for those modules to see if their email tokens could be exposed using e.g. hook_civicrm_tokens. – Coleman May 15 '15 at 22:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.