Drupal News

qed42.com: Securing Cookie for 3rd Party Identity Management in Drupal

  • Securing Cookie for 3rd Party Identity Management in Drupal Body

    We are in an era where we see a lots of third party integrations being done in projects. In Drupal based projects, cookie management is done via Drupal itself to maintain session, whether it be a pure Drupal project or decoupled Drupal project,.

    But what when we have a scenario where user’s information is being managed by a third party service and no user information is being saved on Drupal? And when the authentication is done via some other third party services? How can we manage cookie in this case to run our site session and also keep it secure?

    One is way is to set and maintain cookie on our own. In this case, our user’s will be anonymous to Drupal. So, we keep session running based on cookies! The user information will be stored in cookie itself, which then can be validated when a request is made to Drupal.

    We have a php function to set cookie called setCookie() , which we can use to create and destroy cookie. So, the flow will be that a user login request which is made to website is verified via a third party service and then we call setCookie function which sets the cookie containing user information. But, securing the cookie is must, so how do we do that?

    For this, let’s refer to Bakery module to see how it does it. It contains functions for encrypting cookie, setting it and validating it.

    To achieve this in Drupal 8, we will write a helper class let’s say “UserCookie.php” and place it in ‘{modulename}/src/Helper/’. Our cookie helper class will contain static methods for setting cookie and validating cookie. Static methods so that we will be able to call them from anywhere.

    We will have to encrypt cookie before setting it so we will use openssl_encrypt() php function in following manner:

    /** * Encrypts given cookie data. * * @param string $cookieData * Serialized Cookie data for encryption. * * @return string * Encrypted cookie. */ private static function encryptCookie($cookieData) { // Create a key using a string data. $key = openssl_digest(Settings::get('SOME_COOKIE_KEY'), 'sha256'); // Create an initialization vector to be used for encryption. $iv = openssl_random_pseudo_bytes(16); // Encrypt cookie data along with initialization vector so that initialization // vector can be used for decryption of this cookie. $encryptedCookie = openssl_encrypt($iv . $cookieData, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv); // Add a signature to cookie. $signature = hash_hmac('sha256', $encryptedCookie, $key); // Encode signature and cookie. return base64_encode($signature . $encryptedCookie); }
    1. String parameter in openssl_digest can be replaced with any string you feel like that can be used as key. You can keep simple keyword too.
    2. Key used should be same while decryption of data.
    3. Same initialization vector will be needed while decrypting the data, so to retrieve it back we append this along with cookie data string.
    4. We also add a signature which is generate used the same key used above. We will verify this key while validating cookie.
    5. Finally, we encode both signature and encrypted cookie data together.

    For setting cookie:

    /** * Set cookie using user data. * * @param string $name * Name of cookie to store. * @param mixed $data * Data to store in cookie. */ public static function setCookie($name, $data) { $data = (is_array($data)) ? json_encode($data) : $data; $data = self::encrypt($data); setcookie($name, $cookieData,Settings::get('SOME_DEFAULT_COOKIE_EXPIRE_TIME'), '/'); }

    Note: You can keep 'SOME_COOKIE_KEY' and 'SOME_DEFAULT_COOKIE_EXPIRE_TIME' in your settings.php. Settings::get() will fetch that for you.
    Tip: You can also append and save expiration time of cookie in encrypted data itself so that you can also verify that at time of decryption. This will stop anyone from extending the session by setting cookie timing manually.

    Congrats! We have successfully encrypted the user data and set it into a cookie.

    Now let’s see how we can decrypt and validate the same cookie.

    To decrypt cookie:

    /** * Decrypts the given cookie data. * * @param string $cookieData * Encrypted cookie data. * * @return bool|mixed * False if retrieved signature doesn't matches * or data. */ public static function decryptCookie($cookieData) { // Create a key using a string data used while encryption. $key = openssl_digest(Settings::get('SOME_COOKIE_KEY'), 'sha256'); // Reverse base64 encryption of $cookieData. $cookieData = base64_decode($cookieData); // Extract signature from cookie data. $signature = substr($cookieData, 0, 64); // Extract data without signature. $encryptedData = substr($cookieData, 64); // Signature should match for verification of data. if ($signature !== hash_hmac('sha256', $encryptedData, $key)) { return FALSE; } // Extract initialization vector from data appended while encryption. $iv = substr($string, 64, 16); // Extract main encrypted string data which contains profile details. $encrypted = substr($string, 80); // Decrypt the data using key and // initialization vector extracted above. return openssl_decrypt($encrypted, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv); }
    1. We generate the same key using same string parameter given while encryption.
    2. Then we reverse base64 encoding as we need extract signature to verify it.
    3. We generate same signature again as we have used the same key which was used to creating signature while encryption. If doesn’t signatures doesn’t matches, validation fails!
    4. Else, we extract initialization vector from the encrypted data and use to decrypt the data return to be utilized.
    /** * Validates cookie. * * @param string $cookie * Name of cookie. * * @return boolean * True or False based on cookie validation. */ public static function validateCookie($cookie) { if (self::decryptCookie($cookieData)) { return TRUE; } return FALSE; }

    We can verify cookie on requests made to website to maintain our session. You can implement function for expiring cookie for simulating user logout. We can also use decrypted user data out of cookie for serving user related pages.

    navneet.singh Mon, 10/30/2017 - 13:45

    0 sec ago

RSS feed from Drupal site search?

Weekly Drupal beginner questions thread

Why does a node (which I got via node_load) have strings instead of numbers?

Agiledrop.com Blog: AGILEDROP: We can join in the middle of the project

  • When talking about projects, regardless of their size or complexity, one will go through a couple of phases of project management. Let’s say there are five phases of project management:  project conception and initiation;  project definition and planning;  project launch or execution;  project performance and control;  project close.  Although each of those phases has its distinct qualities, they do overlap. And rightly so.  Planning for unplanned events Planning does start with estimating the budget and completion date, but the planning and defining the project sets the… READ MORE

    14 hours 58 min ago

heykarthikwithu: Composer in Drupal 8 - Manage dependencies

Drupal Multisite through Google Cloud Service/Bitnami

ecommence solutions for Drupal 7 with good APIs

  • So I've been tasked with adding a whole bunch of extra functionality to an existing Drupal 7 site with Drupal Commerce.

    The previous developers have setup a system which integrates Drupal Commerce with a 3rd party membership database (through xml api calls). It essentially tells the DB a user has been created, gets an amount that is due based on what fields were entered and then creates an order with Drupal Commerce, once payment is received the site updates the external DB with a payment received call.

    The code is uber convoluted (and practically uncommented/undocumented) and is pushing the limits of what Drupal Commerce can do. Despite breaking occasionally the system works ok - and it processes a large amount of orders and money fine.

    However there's been a feature request to add a whole bunch of functionality to the system, namely:

    Add products to Drupal Commerce with a bunch of attributes (size, colour etc). This would probably be a nightly cron.

    Update stock levels when an order is made a call is made to the database.

    Update stock levels periodically on a cron.

    So the with the research I've been doing most of this should be possible with Drupal Commerce, but it may be super complicated. Also the Drupal Commerce API seems to be pretty limiting, like there's not much in the way of hooks, I think a lot of this can be overcome with rules but it will get messy.

    So at this point I'm thinking it might be easier to rebuild the commerce side of the site with another platform with more API options etc, which I'm guessing would be Shopfiy because it's so popular. Maybe even Ubercart?

    Any thoughts?

    submitted by /u/bleeeer
    [link] [comments]

    23 hours 30 min ago

Looking for ways to organize content into series

  • I am having a hard time trying to figure it out how to organize related content, but published over a series of posts, into something easier to navigate.

    If you publish, lets say, 10 different posts all related to each other, and want to provide some "guide" (even on the front page) to those posts, how can you do that on drupal? Keep in mind that such "lists of posts" can increase in number fast, without being really a new category.

    I thought of creating new posts just to link to each post in that particular "serie", and then using views to put these "series indexes" into some front page block (a "suggested posts" of sort), but I feel like there is some more elegant way to do that.

    Any thoughts?

    And thanks in advance to anyone willing to spend some time thinking about it!

    KR Mauricio

    submitted by /u/MaximusStrongarm
    [link] [comments]

    1 day 11 hours ago