{"componentChunkName":"component---src-templates-blog-list-template-js","path":"/engineering/46","result":{"data":{"allMarkdownRemark":{"edges":[{"node":{"excerpt":"Hi guys! When you write test cases, do you face the problem of sharing your test cases with your team members or having to use multiple…","fields":{"slug":"/engineering/how-to-maintain-test-cases-in-excel-sheets/"},"html":"<p>Hi guys! When you write test cases, do you face the problem of sharing your test cases with your team members or having to use multiple colors for test cases?<br>\nI have a solution for these problems that is to maintain your test cases in an excel sheet.</p>\n<p><strong>Definition</strong><br>\nTest cases are the part of testing by which a product can be tested properly according to a set of requirements.</p>\n<p><strong>Advantages of using test cases in excel sheets</strong></p>\n<ol>\n<li>Easily handle the test cases in the sheet.</li>\n<li>Easily attach links.</li>\n<li>Easily share sheets with team members.</li>\n<li>Easily use multiple colors in a sheet.</li>\n</ol>\n<p><strong>Standard format of Test Cases</strong><br>\nSome common fields that are used in test case writing are:  </p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 40.30769230769231%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAIAAAB2/0i6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAA1klEQVQY04WP2w7CIAyGef8H0sjmG2jmYZkX3pg4D8vcBkynOCgW8JSp8U9TPtqmP5AiXe5ntEiG1SJMo8EhDqok3ER0N6VsEW4mNJvRMgnX0SCPA4zthObzIB33VqM+EZwpeW5lo2RzvTQOTggYtiJ9pZHu2l5sC3PrhgkXwhijNWgwgACWETxbAPNqATgAP0YYY1hRSumH3rkj33pmwjl3znap1zt35FtuD/rpu/Pn+r/OeJKyKH89+5czqlVwlopkWXbI86rsCr9z/CZR10IIXh8LJm4ku8wX4gdfvQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"1\"\n        title=\"1\"\n        src=\"/static/68dd86b15e802f578b434b0c0fb96f69/e5715/1.png\"\n        srcset=\"/static/68dd86b15e802f578b434b0c0fb96f69/a6d36/1.png 650w,\n/static/68dd86b15e802f578b434b0c0fb96f69/e5715/1.png 768w,\n/static/68dd86b15e802f578b434b0c0fb96f69/d0c2f/1.png 1362w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<ol>\n<li>\n<ol>\n<li>\n<p><strong>Test Case Id:</strong> This field is defined by what type of system we are testing. Below are the standard rules:</p>\n<ul>\n<li>If we are making a test case for any application which doesn’t belong to any specific module then ID would start as TEST_ID 1.</li>\n<li>If we are making test cases for any specific module then ID would be used as MOD_ID 1.</li>\n<li>If test case has more than one expected result then we can use test cases as TEST_ID 1.1,TEST_ID 1.2 etc. All these test cases are a sub-part of TEST_ID 1.</li>\n</ul>\n</li>\n</ol>\n</li>\n</ol>\n<p>In this way we can maintain all the test case IDs and if in the future we can get any requirement or change logs then easily add or change the test case using the following  standard rules without changing the test case IDs of previously written test cases.</p>\n<p><strong>Note:</strong> Test Case Id always uses capital letters.</p>\n<ol>\n<li><strong>Feature Of Product:</strong> This field defines the feature of a product for the type of product we are using.The main advantage of maintaining this field is, in the future if any requirements change then we can easily calculate how many test cases are affected by this and we will change or remove the test cases.**</li>\n<li><strong>Feature Description:</strong> This field explains what type of feature we will test on which condition.**</li>\n<li><strong>Steps To Execute:</strong> These are the steps to be executed on the system being tested to get the expected results. Steps should be understandable and correct. They are written and executed according to a sequence.**</li>\n<li><strong>Expected Result:</strong> These are the wanted outputs from the execution steps performed. Results should be clearly defined for every step. It specifies what are the specifications and what we will get from a particular specification.</li>\n<li><strong>Actual Result:</strong> This field has the real result after the performed execution steps on the system under testing. If the result matches with the expected result then we can write as expected.</li>\n<li><strong>Pass/Fail:</strong> If the result is showing according to the expected result, mark as pass and if not get the output according to the expected, result mark as fail. You are using color for status. Use the green color for Pass and red color for Fail.</li>\n<li><strong>Comment:</strong> This column is for additional information for e.g. if status is set to “cannot be tested”,  then tester can give the reason in this column.**</li>\n</ol>\n<p>Here I have explained a very general format, this will cover almost all the scenarios but we can not assure that all the requirements have been covered, you can proceed the following way to cover all requirements.</p>\n<p><strong>Knowing that all the Requirements have been covered</strong><br>\nTo know that all the requirements have been covered, you need to maintain a Traceability Matrix documentation. Let's take a look on how to create this document.</p>\n<p>Traceability Matrix is a document which provides linking between the requirements and the product which we have developed.<br>\nTraceability Matrix can be divided into 2 parts:-</p>\n<ul>\n<li>Summary</li>\n<li>Traceability Matrix</li>\n<li>\n<p><strong>Summary</strong> :-\nThis section contains a summary of requirements like</p>\n<p>1.1 <strong>Item</strong>: This field contains short descriptions of the items which will be tested.<br>\n1.2 <strong>Product Name</strong>: It contains the product name which you want to test.<br>\n1.3 <strong>Product Version</strong>: It contains the product version which you want to test.<br>\n1.4 <strong>Prerequisites</strong>: Prerequisites are the requirement of a system which are<br>\nneeded before we start testing. Prerequisites could be:</p>\n</li>\n<li>A certain page that a user needs to be on</li>\n<li>A certain data that should be in the system</li>\n<li>\n<p>A certain action to be performed before execution steps are performed.  </p>\n<p>Prerequisites should be satisfied before the test case execution starts.</p>\n<p>1.5 <strong>Change Prerequisites</strong>: Changes that were not necessary before but now are necessary for the system.<br>\n1.6 <strong>Exit Criteria</strong>: This field contains the requirements that must be fulfilled<br>\nin order to announce the completion of testing.<br>\n1.7 <strong>Test Summary</strong>: This field contains the status of the product: how many test<br>\ncases are passed, how many are failed, how many are on hold or how many   are  Invalid etc.  </p>\n</li>\n</ul>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 42%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAIAAAB2/0i6AAAACXBIWXMAAAsTAAALEwEAmpwYAAABBklEQVQY042Ou07DMBhG/Q4sPAGvigQzYmBBYspUwUDExEZZaFIGaBGKQpMSbMeXpHVc1TdcR6KV6NCjo0+f5ctvUMyLLM985rO8+qk455RSFvClbVvRdeIP33uFWAoBpm/Th0E8fk5fh8nXZ951nb+wOAzwXkxu0ug2i+9mcVKOGaYIQYxQ715gwBeQPkXR6fH9xcng/Gj0eMZavdnABGMCUU0Zl1KG/27plz5B+fECh1dtci1Hl8syEcoJqcTKeBdSr9bGOWet28WGtTEG8Kbx1YQDxlqttdlB70Mp5XOtFGg4C2/poHGHECZbP7moqjmEhFKE62+EtkIECak5/y/mbJOU/QLx+r0kxIjFkwAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"2\"\n        title=\"2\"\n        src=\"/static/62f1f5a9b79dcaf961c4f6cccdbc249d/e5715/2.png\"\n        srcset=\"/static/62f1f5a9b79dcaf961c4f6cccdbc249d/a6d36/2.png 650w,\n/static/62f1f5a9b79dcaf961c4f6cccdbc249d/e5715/2.png 768w,\n/static/62f1f5a9b79dcaf961c4f6cccdbc249d/d8104/2.png 1365w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<ol start=\"2\">\n<li>\n<p><strong>Traceability Matrix</strong> :  </p>\n<p>Traceability Matrix covers all the product requirements.We can say that it is a document which maps and traces requirements with test cases. Prime fields of this traceability matrix are</p>\n<p>2.1 <strong>Requirement Id</strong>: This field identifies all the testable requirements.<br>\n2.2 <strong>Requirement Description</strong>:  This field contains the short<br>\ndescription of requirements.<br>\n2.3 <strong>Test Case Id</strong>: According to requirements description which test case id is<br>\ncovered.<br>\n2.4 <strong>Status</strong>: Mention here the status of test cases such as passed, failed, on hold or<br>\ninvalid.</p>\n</li>\n</ol>\n<p>As per the image below:  </p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 40.30769230769231%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAIAAAB2/0i6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAxUlEQVQY032P3Q6CMAyFef+HE5MhREi44EYT2GBM5n47x0YmRvFL05wsPT1d1nUdQuha11VVFajwvWmaPD+f8vxSlm3bPr8QYq1l4RkeBjYzSidCMOdcSimEGPpeKanU2gDABpKI2hiTYYy11t7C+eJ9zjmlze0+cGm1gWgwgSSi9q5sHEmcANhGtTFPaX1JveUcmiml8Yb9bQ7AwZvDs6dp2pvjevvJYfIf88/k9Lgm94HRf51gsrEJxtgjwAJJz/Pshe8vRI7PZbvl1Q4AAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"3\"\n        title=\"3\"\n        src=\"/static/f312d4a5a4b6fe22df69c13a72eb8ee9/e5715/3.png\"\n        srcset=\"/static/f312d4a5a4b6fe22df69c13a72eb8ee9/a6d36/3.png 650w,\n/static/f312d4a5a4b6fe22df69c13a72eb8ee9/e5715/3.png 768w,\n/static/f312d4a5a4b6fe22df69c13a72eb8ee9/d2f5c/3.png 1363w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span><br>\nRequirement ID REQ_ID 1 covered in Test Case Id TEST_ID 1 and TEST_ID 2<br>\nRequirement ID REQ_ID 2 covered in Test Case Id TEST_ID 3 ,TEST_ID 4, TEST_ID 5</p>\n<p><strong>Advantages of using Traceability Matrix</strong></p>\n<ol>\n<li>Easily identify missing functionality.</li>\n<li>Easily cover all customer requirements.</li>\n<li>Make sure that all requirements are covered by developers in test cases</li>\n<li>If any change request is made we can easily change in test cases.</li>\n</ol>\n<p>So we can say that test cases are easily handled in excel sheets. We can use multiple colors in excel sheets for test cases, easily attach links with test cases and easily trace test cases.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"November 03, 2015","updated_date":null,"description":"Learn how to maintain test cases in Excel sheets","title":"Maintain Test Cases in Excel Sheets","tags":["Excel","Tes"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.7699115044247788,"src":"/static/d52966b0ae7fdc28820f4c938e52f867/ee604/test_cases.png","srcSet":"/static/d52966b0ae7fdc28820f4c938e52f867/69585/test_cases.png 200w,\n/static/d52966b0ae7fdc28820f4c938e52f867/497c6/test_cases.png 400w,\n/static/d52966b0ae7fdc28820f4c938e52f867/ee604/test_cases.png 800w,\n/static/d52966b0ae7fdc28820f4c938e52f867/f3583/test_cases.png 1200w,\n/static/d52966b0ae7fdc28820f4c938e52f867/e4d72/test_cases.png 1280w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Shefali Yaduvanshi","github":null,"avatar":null}}}},{"node":{"excerpt":"Are you afraid of hackers and feel unsafe for admin and front user to login through same area? No need to worry as in this article, I am…","fields":{"slug":"/engineering/separate-login-page-for-admin-and-user/"},"html":"<p>Are you afraid of hackers and feel unsafe for admin and front user to login through same area?<br>\nNo need to worry as in this article, I am going to guide you with how to create separate login area for admin. Along with that, I will also provide the required steps to disable administrator login through user/login page.</p>\n<p>Please follow the following implementation steps.</p>\n<p><strong>Step by step Guide:</strong></p>\n<ol>\n<li>In the first step, you need to implement <a href=\"https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_menu/7.x\">hook_menu</a> in your module file.</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk11\">t</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;Admin Login Page&#39;</span><span class=\"mtk1\">),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;page callback&#39;</span><span class=\"mtk1\"> =&gt; </span><span class=\"mtk8\">&#39;yourmodule_admin_login_page&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;page arguments&#39;</span><span class=\"mtk1\"> =&gt; </span><span class=\"mtk11\">array</span><span class=\"mtk1\">(),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;access arguments&#39;</span><span class=\"mtk1\"> =&gt; </span><span class=\"mtk11\">array</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;access content&#39;</span><span class=\"mtk1\">),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;type&#39;</span><span class=\"mtk1\"> =&gt; MENU_CALLBACK,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">$menu_items</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}--&gt;</span></span></code></pre>\n<ol start=\"2\">\n<li>After adding menu in module file, the next step is to define the page callback function yourmodule<em>admin</em>login_page. In this function, we’ll define the layout of admin login page using theme.</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">yourmodule_admin_login_page</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk11\">theme</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;yourmodule_admin_login_template&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<ol start=\"3\">\n<li>Now that you have defined page callback function, the next step is to implement hook_theme in your module file.</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">array</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk8\">&#39;template&#39;</span><span class=\"mtk1\"> =&gt; </span><span class=\"mtk8\">&#39;yourmodule-admin_login&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk8\">&#39;render element&#39;</span><span class=\"mtk1\"> =&gt; </span><span class=\"mtk8\">&#39;form&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk8\">&#39;path&#39;</span><span class=\"mtk1\"> =&gt; </span><span class=\"mtk12\">$path</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    ),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">$theme</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}--&gt;</span></span></code></pre>\n<ol start=\"4\">\n<li>After implementation of hook theme in module file, the next step is to implement preprocess function for template file.</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;hidden&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;#value&#39;</span><span class=\"mtk1\"> =&gt; </span><span class=\"mtk8\">&#39;admin_login&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;#name&#39;</span><span class=\"mtk1\"> =&gt; </span><span class=\"mtk8\">&#39;hidden_admin_login_form&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">$variables</span><span class=\"mtk1\">[</span><span class=\"mtk8\">&#39;rendered&#39;</span><span class=\"mtk1\">] = </span><span class=\"mtk11\">drupal_render</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$form</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}--&gt;</span></span></code></pre>\n<p><strong>Note</strong> : In the above code, we have used the hidden element to identify the admin login page.</p>\n<ol start=\"5\">\n<li>After adding menu in module file, the next step is to define the page callback function yourmodule_admin_login_page. In this function, we’ll define the layout of admin login page using theme.</li>\n</ol>\n<p>'yourmodule-admin_login.tpl.php'</p>\n<ol start=\"6\">\n<li>Now paste the following code in yourmodule-admin_login.tpl.php file.</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!--</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">--&gt;</span></span></code></pre>\n<ol start=\"7\">\n<li>After that, clear your website’s cache and check the following url for your admin login page</li>\n</ol>\n<p>URL : <strong>your-site-domain/admin/login</strong></p>\n<p>All above steps are used to show admin login page. But if you want that only administrator can login through page admin/login then follow the following the next steps.</p>\n<ol>\n<li>In this step, you need to implement <a href=\"https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_form_alter/7.x\">hook_form_alter</a> function. In this function we will add custom validation.</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">yourmodule_form_alter</span><span class=\"mtk1\">(&amp;</span><span class=\"mtk12\">$form</span><span class=\"mtk1\">, &amp;</span><span class=\"mtk12\">$form_state</span><span class=\"mtk1\">,</span><span class=\"mtk12\"> $form_id</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">$form_id</span><span class=\"mtk1\"> == </span><span class=\"mtk8\">&#39;user_login&#39;</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$form</span><span class=\"mtk1\">[</span><span class=\"mtk8\">&#39;#validate&#39;</span><span class=\"mtk1\">][] = </span><span class=\"mtk8\">&#39;yourmodule_external_validate&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<ol start=\"2\">\n<li>After that, add the following code to define the custom validation in which only administrator can login.</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">roles);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">$access_granted</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk4\">TRUE</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk11\">form_set_error</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk11\">t</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;Only site administrator can login.&#39;</span><span class=\"mtk1\">));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk4\">FALSE</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}--&gt;</span></span></code></pre>\n<p><strong>Note</strong>: If you want that administrator can’t login through user login page then add following code to do this.</p>\n<p>Add the mentioned code in function <strong>yourmodule_external_validate</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">roles);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">$user_access_granted</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk11\">form_set_error</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk11\">t</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;Only front user can login.&#39;</span><span class=\"mtk1\">));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk4\">FALSE</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk4\">TRUE</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}--&gt;</span></span></code></pre>\n<p>Complete code of function yourmodule_external_validate looks like:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">roles);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">$access_granted</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk4\">TRUE</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk11\">form_set_error</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk11\">t</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;Only site administrator can login.&#39;</span><span class=\"mtk1\">));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk4\">FALSE</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$user</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">user_load</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$form_state</span><span class=\"mtk1\">[</span><span class=\"mtk8\">&#39;uid&#39;</span><span class=\"mtk1\">]);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$user_access_granted</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">in_array</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;administrator&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">$user</span><span class=\"mtk1\">-&gt;</span><span class=\"mtk12\">roles</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">$user_access_granted</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk11\">form_set_error</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk11\">t</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;Only front user can login.&#39;</span><span class=\"mtk1\">));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk4\">FALSE</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk4\">TRUE</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}--&gt;</span></span></code></pre>\n<p>If you are searching over the web and can’t find anything to create separate admin login page in drupal, Please follow the mentioned above steps and you are done. Also create different layout for this  admin login page.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n</style>","frontmatter":{"date":"October 29, 2015","updated_date":null,"description":null,"title":"Separate Drupal Login Page for Admin and User","tags":["Drupal","Admin Panel"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.9047619047619047,"src":"/static/1946d03fb98b01c53c55a9c4b72a0ab8/ee604/drupal.png","srcSet":"/static/1946d03fb98b01c53c55a9c4b72a0ab8/69585/drupal.png 200w,\n/static/1946d03fb98b01c53c55a9c4b72a0ab8/497c6/drupal.png 400w,\n/static/1946d03fb98b01c53c55a9c4b72a0ab8/ee604/drupal.png 800w,\n/static/1946d03fb98b01c53c55a9c4b72a0ab8/f3583/drupal.png 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Versha Gupta","github":"vershagupta","avatar":null}}}},{"node":{"excerpt":"This tutorial provides a solution to get email alerts, when a unhandled error occurs. For this tutorial, we are using WordPress. Imagine you…","fields":{"slug":"/engineering/how-to-get-email-alerts-for-unhandled-php-exceptions/"},"html":"<p>This tutorial provides a solution to get email alerts, when a unhandled error occurs. For this tutorial, we are using WordPress.</p>\n<p>Imagine you created a php application and it’s running fine.  A couple of days later, a user complains about an error which you’re totally unaware of. Such unhandled errors are very common in php applications. So, to find these issues, we are going to send email notifications whenever an error occurs.</p>\n<p><strong>Step 1.</strong> First of all we need to identify a common application file that include at top of application. in this case the file is “wp-config.php” at the root of your wordpress hosting directory.  </p>\n<p><strong>Step 2.</strong> Let’s add the following line of code in this file under php tag.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">set_error_handler</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;errorHandler&#39;</span><span class=\"mtk1\">); </span><span class=\"mtk3\">// this line of code sets an error handler custom function to handle any php error. And here we pass our custom function that name “errorHandler”</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">createTable</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$array</span><span class=\"mtk1\">){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\">(</span><span class=\"mtk11\">is_array</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$array</span><span class=\"mtk1\">) && </span><span class=\"mtk11\">count</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$array</span><span class=\"mtk1\">)&gt;</span><span class=\"mtk7\">0</span><span class=\"mtk1\">){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">$errorContent</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;&lt;table border = 1&gt;&lt;tr&gt;&lt;td&gt;&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">foreach</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">$array</span><span class=\"mtk1\"> as </span><span class=\"mtk12\">$key</span><span class=\"mtk1\"> =&gt; </span><span class=\"mtk12\">$val</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">$errorContent</span><span class=\"mtk1\"> .= </span><span class=\"mtk12\">$key</span><span class=\"mtk1\"> . </span><span class=\"mtk8\">&quot;&lt;/td&gt;&lt;td&gt;&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">if</span><span class=\"mtk1\">(</span><span class=\"mtk11\">is_array</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$val</span><span class=\"mtk1\">) && </span><span class=\"mtk11\">count</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$val</span><span class=\"mtk1\">)&gt;</span><span class=\"mtk7\">0</span><span class=\"mtk1\">){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">$errorContent</span><span class=\"mtk1\"> .= </span><span class=\"mtk11\">createTable</span><span class=\"mtk1\">(</span><span class=\"mtk11\">json_decode</span><span class=\"mtk1\">(</span><span class=\"mtk11\">json_encode</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$val</span><span class=\"mtk1\">),</span><span class=\"mtk4\">true</span><span class=\"mtk1\">)) ;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span><span class=\"mtk15\">else</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">$errorContent</span><span class=\"mtk1\"> .= </span><span class=\"mtk11\">print_r</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$val</span><span class=\"mtk1\">, </span><span class=\"mtk4\">true</span><span class=\"mtk1\">) ;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">$errorContent</span><span class=\"mtk1\"> .= </span><span class=\"mtk8\">&quot;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">$errorContent</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">/**</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\"> * </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\"> * </span><span class=\"mtk4\">@param</span><span class=\"mtk3\"> </span><span class=\"mtk10\">type</span><span class=\"mtk3\"> $errorNumber        // This parameter returns error number.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\"> * </span><span class=\"mtk4\">@param</span><span class=\"mtk3\"> </span><span class=\"mtk10\">type</span><span class=\"mtk3\"> $errorString           // This parameter returns error string.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\"> * </span><span class=\"mtk4\">@param</span><span class=\"mtk3\"> </span><span class=\"mtk10\">type</span><span class=\"mtk3\"> $errorFile               // This parameter returns path of file in which error found.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\"> * </span><span class=\"mtk4\">@param</span><span class=\"mtk3\"> </span><span class=\"mtk10\">type</span><span class=\"mtk3\"> $errorLine              // This parameter returns line number of file in which you get an error.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\"> * </span><span class=\"mtk4\">@param</span><span class=\"mtk3\"> </span><span class=\"mtk10\">type</span><span class=\"mtk3\"> $errorContext         // This parameter return error context.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\"> */</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">errorHandler</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$errorNumber</span><span class=\"mtk1\">,</span><span class=\"mtk12\"> $errorString</span><span class=\"mtk1\">,</span><span class=\"mtk12\"> $errorFile</span><span class=\"mtk1\">,</span><span class=\"mtk12\"> $errorLine</span><span class=\"mtk1\">,</span><span class=\"mtk12\"> $errorContext</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$emailAddress</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&#39;example@example.com&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$emailSubject</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&#39;Error on my Application&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$emailMessage</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&#39;&lt;h2&gt;Error Reporting on :- &lt;/h2&gt;[&#39;</span><span class=\"mtk1\"> . </span><span class=\"mtk11\">date</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;Y-m-d h:i:s&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk11\">time</span><span class=\"mtk1\">()) . </span><span class=\"mtk8\">&#39;]&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$emailMessage</span><span class=\"mtk1\"> .= </span><span class=\"mtk8\">&quot;&lt;h2&gt;Error Number :- &lt;/h2&gt;&quot;</span><span class=\"mtk1\">.</span><span class=\"mtk11\">print_r</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$errorNumber</span><span class=\"mtk1\">, </span><span class=\"mtk4\">true</span><span class=\"mtk1\">).</span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$emailMessage</span><span class=\"mtk1\"> .= </span><span class=\"mtk8\">&quot;&lt;h2&gt;Error String :- &lt;/h2&gt;&quot;</span><span class=\"mtk1\">.</span><span class=\"mtk11\">print_r</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$errorString</span><span class=\"mtk1\">, </span><span class=\"mtk4\">true</span><span class=\"mtk1\">).</span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$emailMessage</span><span class=\"mtk1\"> .= </span><span class=\"mtk8\">&quot;&lt;h2&gt;Error File :- &lt;/h2&gt;&quot;</span><span class=\"mtk1\">.</span><span class=\"mtk11\">print_r</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$errorFile</span><span class=\"mtk1\">, </span><span class=\"mtk4\">true</span><span class=\"mtk1\">).</span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$emailMessage</span><span class=\"mtk1\"> .= </span><span class=\"mtk8\">&quot;&lt;h2&gt;Error Line :- &lt;/h2&gt;&quot;</span><span class=\"mtk1\">.</span><span class=\"mtk11\">print_r</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$errorLine</span><span class=\"mtk1\">, </span><span class=\"mtk4\">true</span><span class=\"mtk1\">).</span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$emailMessage</span><span class=\"mtk1\"> .= </span><span class=\"mtk8\">&quot;&lt;h2&gt;Error Context :- &lt;/h2&gt;&quot;</span><span class=\"mtk1\">.</span><span class=\"mtk11\">createTable</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$errorContext</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$headers</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;MIME-Version: 1.0&quot;</span><span class=\"mtk1\"> . </span><span class=\"mtk8\">&quot;rn&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$headers</span><span class=\"mtk1\"> .= </span><span class=\"mtk8\">&quot;Content-type:text/html;charset=UTF-8&quot;</span><span class=\"mtk1\"> . </span><span class=\"mtk8\">&quot;rn&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">mail</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$emailAddress</span><span class=\"mtk1\">, </span><span class=\"mtk12\">$emailSubject</span><span class=\"mtk1\">, </span><span class=\"mtk12\">$emailMessage</span><span class=\"mtk1\">, </span><span class=\"mtk12\">$headers</span><span class=\"mtk1\">); </span><span class=\"mtk3\">// you may use SMTP, default php mail service OR other email sending process</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p><strong>Step 3.</strong> Now save the file and upload on server.</p>\n<p>Whenever we got any error in wordpress then above code will send an email to given email-address (example@example.com). You can use the above code on production websites to improve application performance and track all errors that’s are missed.</p>\n<p>Similarly we can use above code in drupal, joomla, and many other content management systems.<br>\nCommon config files on other platforms are listed below:</p>\n<table>\n<thead>\n<tr>\n<th><strong>CMS/application name</strong></th>\n<th><strong>Location of common file</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>4Images Gallery</td>\n<td>/config.php</td>\n</tr>\n<tr>\n<td>B2 Evolution</td>\n<td>/conf/_basic_config.php</td>\n</tr>\n<tr>\n<td>Boonex Dolphin</td>\n<td>/inc/header.inc.php</td>\n</tr>\n<tr>\n<td>Concrete5</td>\n<td>/config/site.php</td>\n</tr>\n<tr>\n<td>Coppermine Photo Gallery</td>\n<td>/include/config.inc.php</td>\n</tr>\n<tr>\n<td>Crafty Syntax Live Help</td>\n<td>/config.php</td>\n</tr>\n<tr>\n<td>Cube Cart</td>\n<td>/includes/global.inc.php</td>\n</tr>\n<tr>\n<td>dotProject</td>\n<td>/includes/config.php</td>\n</tr>\n<tr>\n<td>Drupal</td>\n<td>/sites/default/settings.php</td>\n</tr>\n<tr>\n<td>e107</td>\n<td>/e107_config.php</td>\n</tr>\n<tr>\n<td>FAQMasterFlex</td>\n<td>/faq_config.php</td>\n</tr>\n<tr>\n<td>Gallery</td>\n<td>/config.php</td>\n</tr>\n<tr>\n<td>Geeklog</td>\n<td>/db-config.php or /siteconfig.php or /lib-common.php</td>\n</tr>\n<tr>\n<td>glfusion</td>\n<td>/private/db-config.php</td>\n</tr>\n<tr>\n<td>Hotaru</td>\n<td>/hotaru_settings.php</td>\n</tr>\n<tr>\n<td>Joomla</td>\n<td>/configuration.php</td>\n</tr>\n<tr>\n<td>LiveSite</td>\n<td>/livesite/config.php</td>\n</tr>\n<tr>\n<td>LifeType</td>\n<td>/config/config.properties.php</td>\n</tr>\n<tr>\n<td>Mambo</td>\n<td>/configuration.php</td>\n</tr>\n<tr>\n<td>Marketecture</td>\n<td>/include/config.php</td>\n</tr>\n<tr>\n<td>MODx</td>\n<td>/manager/includes/config.inc.php</td>\n</tr>\n<tr>\n<td>Moodle</td>\n<td>/config.php</td>\n</tr>\n<tr>\n<td>MyBB</td>\n<td>/inc/config.php</td>\n</tr>\n<tr>\n<td>Noahs Classifieds</td>\n<td>/app/config.php</td>\n</tr>\n<tr>\n<td>Nucleus</td>\n<td>/config.php</td>\n</tr>\n<tr>\n<td>ocPortal</td>\n<td>/info.php</td>\n</tr>\n<tr>\n<td>OpenCart</td>\n<td>/config.php or /admin/config.php</td>\n</tr>\n<tr>\n<td>osCommerce</td>\n<td>/includes/configure.php or /admin/includes/configure.php</td>\n</tr>\n<tr>\n<td>Oxwall</td>\n<td>/ow_includes/config.php</td>\n</tr>\n<tr>\n<td>PHP-Nuke</td>\n<td>/config.php</td>\n</tr>\n<tr>\n<td>phpBB</td>\n<td>/config.php</td>\n</tr>\n<tr>\n<td>phpFormGenerator</td>\n<td>/index.php or /mysql.class.php</td>\n</tr>\n<tr>\n<td>phpFreeChat</td>\n<td>/forms/admin/config.inc.php (only if you have saved form input to a database)</td>\n</tr>\n<tr>\n<td>PHPlist</td>\n<td>/config/config.php</td>\n</tr>\n<tr>\n<td>phpMyDirectory</td>\n<td>/defaults.php</td>\n</tr>\n<tr>\n<td>phpWCMS</td>\n<td>/include/inc_conf/conf.inc.php</td>\n</tr>\n<tr>\n<td>phpWebSite</td>\n<td>/conf/config.php</td>\n</tr>\n<tr>\n<td>PhpWiki</td>\n<td>/admin.php or /lib/config.php</td>\n</tr>\n<tr>\n<td>Pligg</td>\n<td>/libs/dbconnect.php</td>\n</tr>\n<tr>\n<td>Post-Nuke</td>\n<td>/config.php</td>\n</tr>\n<tr>\n<td>PrestaShop</td>\n<td>/config/settings.inc.php</td>\n</tr>\n<tr>\n<td>Saurus CMS</td>\n<td>/config.php</td>\n</tr>\n<tr>\n<td>ShopSite</td>\n<td>/includes/configure.php or /admin/includes/configure.php</td>\n</tr>\n<tr>\n<td>Siteframe</td>\n<td>/config.php</td>\n</tr>\n<tr>\n<td>Simple Machines Forum</td>\n<td>/Settings.php</td>\n</tr>\n<tr>\n<td>Soholaunch</td>\n<td>/sohoadmin/config/isp.conf.php</td>\n</tr>\n<tr>\n<td>SugarCRM</td>\n<td>/config.php</td>\n</tr>\n<tr>\n<td>Textpattern</td>\n<td>/textpattern/config.php</td>\n</tr>\n<tr>\n<td>TikiWiki</td>\n<td>/db/local.php</td>\n</tr>\n<tr>\n<td>Tomato Cart</td>\n<td>/includes/configure.php</td>\n</tr>\n<tr>\n<td>TYPO3</td>\n<td>/typo3conf/localconf.php</td>\n</tr>\n<tr>\n<td>WebCalendar</td>\n<td>/includes/settings.php</td>\n</tr>\n<tr>\n<td>WHMCS</td>\n<td>/configuration.php</td>\n</tr>\n<tr>\n<td>WordPress</td>\n<td>/wp-config.php</td>\n</tr>\n<tr>\n<td>X7 Chat</td>\n<td>/config.php</td>\n</tr>\n<tr>\n<td>Xoops</td>\n<td>/mainfile.php</td>\n</tr>\n<tr>\n<td>Zen Cart</td>\n<td>/includes/configure.php or /admin/includes/configure.php</td>\n</tr>\n<tr>\n<td>Zikula</td>\n<td>/config.php</td>\n</tr>\n</tbody>\n</table>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n</style>","frontmatter":{"date":"October 26, 2015","updated_date":null,"description":null,"title":"How to Get Email Alerts for Unhandled PHP Exceptions","tags":["PHP","Email"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1,"src":"/static/4a396ee0a823348eb1c43701756c8981/7d145/email-alerts-unhandled-php.png","srcSet":"/static/4a396ee0a823348eb1c43701756c8981/69585/email-alerts-unhandled-php.png 200w,\n/static/4a396ee0a823348eb1c43701756c8981/497c6/email-alerts-unhandled-php.png 400w,\n/static/4a396ee0a823348eb1c43701756c8981/7d145/email-alerts-unhandled-php.png 610w","sizes":"(max-width: 610px) 100vw, 610px"}}},"author":{"id":"Team LoginRadius","github":"LoginRadius","avatar":null}}}},{"node":{"excerpt":"So last week while I was setting the analyzers on ElasticSearch settings for Email field, it took me some good time to find the perfect…","fields":{"slug":"/engineering/elastic-search-analyzers-for-emails/"},"html":"<p>So last week while I was setting the analyzers on ElasticSearch settings for Email field, it took me some good time to find the perfect custom analyzer for my purpose, so I feel it might be useful to share this with someone who needs it.</p>\n<blockquote>\n<p>When a document is indexed, its individual fields are subject to the analyzing and tokenizing filters that can transform and normalize the data in the fields. For example — removing blank spaces, removing html code, stemming, removing a particular character and replacing it with another. At indexing time as well as at query time you may need to do some of the above or similiar operations. For example, you might perform a Soundex transformation (a type of phonic hashing) on a string to enable a search based upon the word and upon its 'sound-alikes'.</p>\n</blockquote>\n<p>Let me briefly explain what I am trying to do with my Email field. The email addresses will be stored as a comma separated string with potentially multiple email addresses, and what I am expecting is after the to search to retrieve the matching results. Besides the exact match like search for <code>\"john.doe@gmail.com\"</code>, I also want to be able to search for <code>\"john.doe\"</code> or <code>\"gmail.com\"</code> to retrieve the relative information.</p>\n<p>Here is the full schema for it:</p>\n<ol>\n<li>{\"email\": \"john.doe@gmail.com\"}</li>\n<li>{\"email\": \"john.doe@gmail.com, john.doe@outlook.com\"}</li>\n<li>{\"email\": \"hello-john.doe@outlook.com\"}</li>\n<li>{\"email\": \"john.doe@outlook.com\"}</li>\n<li>{\"email\": \"john@yahoo.com\"}</li>\n</ol>\n<p>And the search schema is:<br>\n[Search > Response]<br>\n\"john.doe@gmail.com\" > 1,2<br>\n\"john.doe@outlook.com\" > 2,4<br>\n\"john@yahoo.com\" > 5<br>\n\"john.doe\" > 1,2,3,4<br>\n\"john\" > 1,2,3,4,5<br>\n\"gmail.com\" > 1,2<br>\n\"outlook.com\" > 2,3,4</p>\n<p>If you decide to keep reading, then it means you have the same needs as I did so I hope the following solution can actually help.<br>\nSo... In the official documentation they did have a good solution but it was not easy to find, at least for me, by using regular expression:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk8\">&quot;settings&quot;</span><span class=\"mtk1\"> : {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk8\">&quot;analysis&quot;</span><span class=\"mtk12\"> :</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">         </span><span class=\"mtk8\">&quot;filter&quot;</span><span class=\"mtk12\"> :</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;email&quot;</span><span class=\"mtk12\"> :</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">               </span><span class=\"mtk8\">&quot;type&quot;</span><span class=\"mtk12\"> :</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;pattern_capture&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">               </span><span class=\"mtk8\">&quot;preserve_original&quot;</span><span class=\"mtk12\"> :</span><span class=\"mtk1\"> </span><span class=\"mtk7\">1</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">               </span><span class=\"mtk8\">&quot;patterns&quot;</span><span class=\"mtk12\"> :</span><span class=\"mtk1\"> [</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                  </span><span class=\"mtk8\">&quot;([^@]+)&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                  </span><span class=\"mtk8\">&quot;(</span><span class=\"mtk6\">\\p</span><span class=\"mtk8\">{L}+)&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                  </span><span class=\"mtk8\">&quot;(</span><span class=\"mtk6\">\\d</span><span class=\"mtk8\">+)&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                  </span><span class=\"mtk8\">&quot;@(.+)&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">               ]</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">         },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">         </span><span class=\"mtk8\">&quot;analyzer&quot;</span><span class=\"mtk12\"> :</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;email&quot;</span><span class=\"mtk12\"> :</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">               </span><span class=\"mtk8\">&quot;tokenizer&quot;</span><span class=\"mtk12\"> :</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;uax_url_email&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">               </span><span class=\"mtk8\">&quot;filter&quot;</span><span class=\"mtk12\"> :</span><span class=\"mtk1\"> [ </span><span class=\"mtk8\">&quot;email&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;lowercase&quot;</span><span class=\"mtk1\">,  </span><span class=\"mtk8\">&quot;unique&quot;</span><span class=\"mtk1\"> ]</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">         }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>This setting will perfectly address the issues from above, and do not generate way to much tokens in your ES cluster.<br>\nAt the end I want to share two good gadgets that I found very helpful with ES analyzers and regular expression.</p>\n<ol>\n<li><strong>Inquisitor:</strong><br>\nThis Elastic Search tool allows you to quickly apply different analyzers, tokenizers and filters to your input, fork it here:<br>\n<a href=\"https://github.com/polyfractal/elasticsearch-inquisitor\">Elasticsearch Inquisitor</a></li>\n<li><strong>regex 101:</strong>\nTo quickly test out your regular expression, try this link: <a href=\"https://regex101.com/\">regex101</a></li>\n</ol>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk6 { color: #D7BA7D; }\n</style>","frontmatter":{"date":"October 15, 2015","updated_date":null,"description":null,"title":"ElasticSearch Analyzers for Emails","tags":["Elastic Search","Analyzers"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.9230769230769231,"src":"/static/db4c939fb2ba73abdc984760c0082348/ee604/elastic-search.png","srcSet":"/static/db4c939fb2ba73abdc984760c0082348/69585/elastic-search.png 200w,\n/static/db4c939fb2ba73abdc984760c0082348/497c6/elastic-search.png 400w,\n/static/db4c939fb2ba73abdc984760c0082348/ee604/elastic-search.png 800w,\n/static/db4c939fb2ba73abdc984760c0082348/f3583/elastic-search.png 1200w,\n/static/db4c939fb2ba73abdc984760c0082348/5707d/elastic-search.png 1600w,\n/static/db4c939fb2ba73abdc984760c0082348/a16c9/elastic-search.png 3422w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Lucius Yu","github":null,"avatar":null}}}},{"node":{"excerpt":"Integrating social into your site can drastically improve user engagement with your platform. Below are a few useful solutions and…","fields":{"slug":"/engineering/simple-social-media-solutions/"},"html":"<p>Integrating social into your site can drastically improve user engagement with your platform. Below are a few useful solutions and implementation instructions.</p>\n<h2 id=\"social-login\" style=\"position:relative;\"><a href=\"#social-login\" aria-label=\"social login permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Social Login</h2>\n<p>Social Login, also known as Social Sign On, Allows you to bypass traditional registration forms and utilize the systems in place by social providers in order to retrieve a copy of the users data and a unique identifier for the user that can be used to identify that user in your system.</p>\n<p>The following guides go over setting up Social Login with a few common Social Providers:<br>\nFacebook: <a href=\"/implement-facebook-social-login/\">How to Implement Facebook Social Login</a><br>\nTwitter: <a href=\"/integrating-twitter-social-login/\">Integrating Twitter Social Login</a><br>\nLinkedIn: <a href=\"/integrate-linkedin-social-login-website/\">Integrating LinkedIn Social Login on a Website</a></p>\n<h2 id=\"social-sharing\" style=\"position:relative;\"><a href=\"#social-sharing\" aria-label=\"social sharing permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Social Sharing</h2>\n<p>Most major social providers offer an easy tool to formulate and include sharing buttons on your pages. Below is an example of setting up an easy to use social sharing button with Facebook:</p>\n<ol>\n<li>Include the Facebook JavaScript SDK on your page:</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!----&gt;</span></span></code></pre>\n<ol start=\"6\">\n<li>\n<p>Next include the div that will contain the sharing button on your page with the following data attributes:</p>\n<ol>\n<li>data-href - Set this to the URL that you want to share.</li>\n<li>data-layout - Set this to one of the following to control the style of button that is displayed:<br>\na. box_count<br>\nb. button_count<br>\nc. button<br>\nd. icon_link<br>\ne. icon<br>\nf. link</li>\n</ol>\n</li>\n</ol>\n<p>Sample Div:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!-- --&gt;</span></span></code></pre>\n<p>You can find information on generating sharing links with other providers in the following locations:<br>\n<a href=\"https://about.twitter.com/resources/buttons\">Twitter</a>  </p>\n<p>Or you can contribute to our open source project on github- <a href=\"https://github.com/social9\">Github-Social9</a></p>\n<h2 id=\"follow-company\" style=\"position:relative;\"><a href=\"#follow-company\" aria-label=\"follow company permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Follow Company</h2>\n<p>Follow buttons work very much the same as the social sharing buttons above. Simply include the relevant SDK and div with some customizations and users will be able to follow(and un-follow) your brand directly from your page.</p>\n<p>Below is an example of setting up a Twitter follow button:</p>\n<ol>\n<li>Include Twitters JavaScript SDK using their provided script:</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!----&gt;</span></span></code></pre>\n<ol start=\"6\">\n<li>Include a link tag in the location that you would like to display your follow button:</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!-- </span><span class=\"mtk12\">Follow</span><span class=\"mtk1\"> @</span><span class=\"mtk12\">TwitterDev</span><span class=\"mtk1\"> --&gt;</span></span></code></pre>\n<p>You can set the data attributes in the above link to control various aspects of the follow button.</p>\n<p>Find information on generating follow buttons for other social providers in the following locations:<br>\n<a href=\"https://developers.facebook.com/docs/archive/docs/plugins/follow-button/\">Facebook</a>  </p>\n<h2 id=\"social-linking\" style=\"position:relative;\"><a href=\"#social-linking\" aria-label=\"social linking permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Social Linking</h2>\n<p>One of the most common and easy to configure social integrations is setting up links to your companies Social profiles.<br>\nAll you need to do is create a link tag on your page:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!--</span><span class=\"mtk12\">Facebook</span><span class=\"mtk1\">--&gt;</span></span></code></pre>\n<p>You can improve upon this by utilizing one of the Social providers branded icons to better display the linking UX. Get a copy of Facebooks Branded Icon.<br>\nYou can store the image locally and include it in the a tag:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!--&lt;</span><span class=\"mtk12\">img</span><span class=\"mtk1\"> </span><span class=\"mtk12\">src</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">alt</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Facebook&quot;</span><span class=\"mtk1\">&gt; --&gt;</span></span></code></pre>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>Now that you have setup the above social features your users will have a variety of touch-points to keep them active and interacting with your site, seamlessly driving user conversions and making brand ambassadors of your users.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n</style>","frontmatter":{"date":"October 08, 2015","updated_date":null,"description":null,"title":"Social Media Solutions","tags":["Social Media","Social Login"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.408450704225352,"src":"/static/b3a4226418ae955228bf1bc38289c30a/ee604/social-media.png","srcSet":"/static/b3a4226418ae955228bf1bc38289c30a/69585/social-media.png 200w,\n/static/b3a4226418ae955228bf1bc38289c30a/497c6/social-media.png 400w,\n/static/b3a4226418ae955228bf1bc38289c30a/ee604/social-media.png 800w,\n/static/b3a4226418ae955228bf1bc38289c30a/40ffe/social-media.png 960w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Karl Wittig","github":null,"avatar":null}}}},{"node":{"excerpt":"Introduction Authentication and authorization both are most important things for any system and application. This blog starts with…","fields":{"slug":"/engineering/alternate-authentication-asp/"},"html":"<p><strong>Introduction</strong></p>\n<p>Authentication and authorization both are most important things for any system and application. This blog starts with authentication and authorization concepts and after that explains the three default important ways and three custom authentication ways for doing authentication and authorization i.e. windows, forms ,passport, multipass, JWT  and SAML authentication. Plus, in this blog I will explain some fundamental concepts about the different authentication system.</p>\n<p><strong>Authentication and Authorization</strong></p>\n<p>Authentication is the process for checking the identity of a user based on the user’s credentials. Generally, user’s credentials are  in the form of user ID and password, and we check their credentials from database or equivalent alternative, if it exists then user is a valid candidate for next process - authorization.</p>\n<p>Authorization also known as “Permission Control” will come after authentication. Authorization is the process of deciding what kind of resource a user can access based on their identity and checking whether the authenticated user has sufficient rights to access the requested resources. Typically a resource can be an ASP.NET web page, media files (MP4, GIF, JPEG etc), compressed file (ZIP, RAR) etc.</p>\n<p><strong>ASP.NET default authentication Providers</strong></p>\n<p><strong>1. Form Authentication</strong></p>\n<p>Normally, form authentication is based on cookies, the authentication and permission settings are stored in cookies. However, we can also use form authentication without cookies, and in cookie-less form authentication we can use query string for passing user details. Remember, the key concept is always ONLY allow the user with correct credential also enough permission to view certain resources, so we need to capture their information and compare with what we have stored in the database. And no matter what kind of form authentication we use, after we receive the data on server end, we will compare them with the data stored in any storage method/provider. For example, we can store username and password in the web.config file, a JSON file, or a database table.</p>\n<p>Forms authentication flow:</p>\n<ol>\n<li>When a user requests a page for the application, ASP.NET checks session cookie. If the cookie exists and valid, ASP.NET assumes the user is authenticated and processes the request.</li>\n<li>If session cookies does not exists or not valid then it redirect to login form.</li>\n<li>User will enter username and password and if they are valid then he will get authenticated and authorized.</li>\n</ol>\n<p> <strong>2. Passport Authentication</strong></p>\n<p>Passport authentication is a centralized authentication service provided by Microsoft. The .NET Passport single sign-in service. When we use passport authentication then user authentication in your application is managed by Microsoft's passport service. Passport authentication uses encrypted cookies to manage the authentication.</p>\n<p><strong>How Password authentication works</strong> Users do not need to retype their sign-in name and password when moving from site to site. Those .NET Passport–enabled sites will issue a set of encrypted cookies in the .NET Passport central servers' domain to facilitate silent and seamless sign-in across sites. In some cases, sites owners will first redirect their end-users to .NET Passport sign-in and to authenticate upon first viewing of their site. If the users are logged in already, they'll get authenticated by ASP.NET, and if they are not logged in they will get redirected to passport servers (i.e hotmail, Live etc.)  to login first. If user successfully authenticates himself, it will return a token to your website.</p>\n<p><strong>3. Windows Authentication</strong></p>\n<p>We use windows authentication when we are creating a web application for a limited number of users who already have Windows account and this type of authentication is quite useful in an intranet environment. This authentication method uses local users windows account 'credentials' for to validate the user. Dot Net web application generally hosted on IIS(Internet Information Server) so the requests go directly to IIS to provide the authentication process in a Windows-based authentication model.</p>\n<p>The entire responsibility of authentication is done by IIS. It first takes the user’s credentials from the domain login. If this process fails, IIS displays an alert dialog box so the user can enter or re-enter his login information.</p>\n<p>Windows authentication have some advantages and disadvantages:</p>\n<p><strong>Windows authentication Advantage</strong></p>\n<ol>\n<li>Developers need to write less line of code for managing user's authentication.</li>\n<li>Users can use their existing windows accounts for login.</li>\n</ol>\n<p><strong>Windows authentication dis-Advantage</strong></p>\n<ol>\n<li>You can't control windows authentication process.</li>\n<li>Windows authentication only works on Microsoft OS you can't use it on others OS.</li>\n</ol>\n<p> <strong>4. Custom authentication Provider</strong></p>\n<ol>\n<li><strong>Multipass</strong></li>\n</ol>\n<p>Multipass authentication is a single sign on authentication. Suppose you have multiple sites and you want to create a single account for a user on both sites then you can use Single Sign-On. Single Sign-On is authentication system it allow user to share his authentication details with your there site. This allows a seamless experience for your users without forcing them to create a separate account on your second site. A multipass is simply a hash of keys and values, provided as an AES encrypted JSON hash.</p>\n<ol start=\"2\">\n<li><strong>JWT (JSON Web token)</strong></li>\n</ol>\n<p>JWTs represent a set of claims as a JSON object that is encoded in a JWS and/or JWE structure. This JSON object is called “JWT Claims Set”. The JSON object consists of zero or more name/value pairs (or members), where the names are strings and the values are arbitrary JSON values. These members are the claims represented by the JWT.</p>\n<p>Your JWTs can contain any information you want; the user's name, birthdate, email, etc. You do this with claims based authorization. You then just tell your provider to make a JWT with these claims from the claims principle.</p>\n<ol start=\"3\">\n<li><strong>SAML (Security Assertion Markup Language)</strong></li>\n</ol>\n<p>SAML - Security Assertion Markup Language SAML. SAML is developed by the Security Services Technical Committee of \"Organization for the Advancement of Structured Information Standards\" (OASIS). SAML is an XML-based framework for exchanging user authentication. The purpose of SAML is to enable Single Sign-On for web applications across various domains.</p>\n<p>SAML have three components: assertions, protocol, and binding. Assertions are authentication, attribute, and authorization. Authentication assertion validates the user's identity. Attribute assertion contains specific information about the user. And authorization assertion identifies user role and permissions.</p>\n<p>SAML works with multiple protocols including Hypertext Transfer Protocol (HTTP), Simple Mail Transfer Protocol (SMTP), File Transfer Protocol (FTP) and also supports SOAP</p>\n<p><strong>Summary</strong></p>\n<p>Different authentication methods are available, and website’s owner always gets confused about which authentication method they should use, here I have explained some of the popular authentication and authorization methods, hope it made it a little bit clear for you. And I will provide some in-depth details about each type of authentication in my next blog, <strong>happy coding</strong>.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"October 01, 2015","updated_date":null,"description":"Learn types of Authentication in Asp.Net and how it plays an important role in any system.","title":"Types of Authentication in Asp.Net","tags":["Engineering","Authentication","Asp.Net","Multipass","JWT","JSON Web Token"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1,"src":"/static/09593e63090dd5b6ec6f5258209a953b/6d161/alternate-authentication-asp-dot-net1-150x150.png","srcSet":"/static/09593e63090dd5b6ec6f5258209a953b/6d161/alternate-authentication-asp-dot-net1-150x150.png 150w","sizes":"(max-width: 150px) 100vw, 150px"}}},"author":{"id":"Team LoginRadius","github":"LoginRadius","avatar":null}}}}]},"markdownRemark":{"excerpt":"Google has prepared a roadmap to restrict third-party cookies in Chrome. Since 04 January 2024, Chrome has rolled out third-party cookie…","fields":{"slug":"/engineering/identity-impact-of-google-chrome-thirdparty-cookie-restrictions/"},"html":"<p>Google has prepared a roadmap to restrict third-party cookies in Chrome. Since 04 January 2024, Chrome has rolled out third-party cookie restrictions for 1% of stable clients and 20% of Canary, Dev, and Beta clients.</p>\n<p><strong>What does it mean for user authentication?</strong></p>\n<p>On one hand, Google believes third-party cookies are widely used for cross-site tracking, greatly affecting user privacy. Hence, Google wants to phase out (or restrict) supporting third-party cookies in Chrome by early Q2 2025 (subject to regulatory processes).</p>\n<p>On the other hand, Google introduced Privacy Sandbox to support the use cases (other than cross-site tracking and advertising) previously implemented using third-party cookies.</p>\n<p>In this article, we’ll discuss:</p>\n<ul>\n<li>How is user authentication (identity) affected?</li>\n<li>What is Google offering as part of Privacy Sandbox to support various identity use cases when third-party cookies are phased out?</li>\n</ul>\n<h2 id=\"how-is-user-authentication-affected\" style=\"position:relative;\"><a href=\"#how-is-user-authentication-affected\" aria-label=\"how is user authentication affected permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How is User Authentication Affected?</h2>\n<p>Third-party cookie restrictions affect user authentication in three ways, as follows.</p>\n<h3 id=\"external-identity-providers\" style=\"position:relative;\"><a href=\"#external-identity-providers\" aria-label=\"external identity providers permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>External Identity Providers</h3>\n<p>If your website or app uses an external Identity Provider (IdP) — like LoginRadius, the IdP sets a third-party cookie when the user authenticates on your app.</p>\n<h3 id=\"web-sso\" style=\"position:relative;\"><a href=\"#web-sso\" aria-label=\"web sso permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Web SSO</h3>\n<p>If you have multiple apps across domains within your organization and authentication is handled using an IdP (internal or external) with web SSO, you already use third-party cookies to facilitate seamless access for each user using a single set of credentials.</p>\n<p>If you have implemented web SSO with one primary domain and multiple sub-domains of the primary domain, third-party cookie restrictions may not apply. For now, Google doesn’t consider the cookies set by sub-domains as third-party cookies, although this stance may change in the future.</p>\n<p>For example, you have apps at <code>example.com</code>, <code>travel.example.com</code>, <code>stay.example.com</code>, and web SSO is handled by <code>auth.example.com</code>. In this case, third-party cookie restrictions don’t apply.</p>\n<h3 id=\"federated-sso\" style=\"position:relative;\"><a href=\"#federated-sso\" aria-label=\"federated sso permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Federated SSO</h3>\n<p>Federated SSO is similar to, albeit different from, web SSO. It can handle multiple IdPs and applications—aka., Service Providers (SPs)—spanning multiple organizations. It can also implement authentication scenarios that are usually implemented through web SSO.</p>\n<p>Usually, authentication is handled on a separate pop-up or page when the user wants to authenticate rather than on the application or website a user visits. </p>\n<p>For example, you already use federated SSO if you facilitate authentication for a set of apps through multiple social identity providers as well as traditional usernames and passwords.</p>\n<blockquote>\n<p><strong>Note</strong>: It is also possible to store tokens locally, not within cookies. In this case, third-party cookie restrictions won’t affect token-based authentication. However, the restrictions still affect authentication where tokens are stored within third-party cookies (a common and secure method).</p>\n</blockquote>\n<h2 id=\"chromes-alternatives-for-third-party-cookies\" style=\"position:relative;\"><a href=\"#chromes-alternatives-for-third-party-cookies\" aria-label=\"chromes alternatives for third party cookies permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Chrome’s Alternatives for Third-Party Cookies</h2>\n<p>Google has been developing alternative features and capabilities for Chrome to replace third-party cookies as part of its Privacy Sandbox for Web initiative.</p>\n<p>Specific to authentication, Google recommends the following:</p>\n<ol>\n<li>Cookies Having Independent Partitioned State (CHIPS)</li>\n<li>Storage Access API</li>\n<li>Related Website Sets</li>\n<li>Federated Credential Management (FedCM) API</li>\n</ol>\n<h3 id=\"cookies-having-independent-partitioned-state-chips\" style=\"position:relative;\"><a href=\"#cookies-having-independent-partitioned-state-chips\" aria-label=\"cookies having independent partitioned state chips permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Cookies Having Independent Partitioned State (CHIPS)</h3>\n<p><a href=\"https://developers.google.com/privacy-sandbox/3pcd/chips\">CHIPS</a> are a restricted way of setting third-party cookies on a top-level site without making them accessible on other top-level sites. Thus, they limit cross-site tracking and enable specific cross-site functionalities, such as maps, chat, and payment embeds.</p>\n<p>For example, a user visits <code>a.com</code> with a map embed from <code>map-example.com</code>, which can set a partitioned cookie that is only accessible on a.com. </p>\n<p>If the user visits <code>b.com</code> with a map embed from <code>map-example.com</code>, it cannot access the partitioned cookie set on <code>a.com</code>. It has to create a separate partitioned cookie specific to <code>b.com</code>, thus blocking cross-site tracking yet allowing limited cross-site functionality.</p>\n<p>You should specifically opt for partitioned cookies (CHIPS), which are set with partitioned and secure cookie attributes.</p>\n<p>If you’re using an external identity provider for your application, CHIPS is a good option to supplant third-party cookie restrictions. </p>\n<p>However, CHIPS may not be ideal if you have a web SSO or federated SSO implementation. It creates separate partitioned cookies for each application with a separate domain, which can increase complexity and create compatibility issues.</p>\n<h3 id=\"storage-access-api\" style=\"position:relative;\"><a href=\"#storage-access-api\" aria-label=\"storage access api permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Storage Access API</h3>\n<p>With <a href=\"https://developers.google.com/privacy-sandbox/3pcd/storage-access-api\">Storage Access API</a>, you can access the local storage in a third-party context through iframes, similar to when users visit it as a top-level site in a first-party context. That is, it gives access to unpartitioned cookies and storage.</p>\n<p>Storage Access API requires explicit user approval to grant access, similar to locations, camera, and microphone permissions. If the user denies access, unpartitioned cookies and storage won’t be accessible in a third-party context.</p>\n<p>It is most suitable when loading cross-site resources and interactions, such as:</p>\n<p>Verifying user sessions when allowing interactions on an embedded social post or providing personalization for an embedded video.\nEmbedded documents requiring user verification status to be accessible.</p>\n<p>As it requires explicit user approval, it is advisable to use Storage Access API when you can’t implement an identity use case with the other options.</p>\n<h3 id=\"related-website-sets\" style=\"position:relative;\"><a href=\"#related-website-sets\" aria-label=\"related website sets permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Related Website Sets</h3>\n<p>With <a href=\"https://developers.google.com/privacy-sandbox/3pcd/related-website-sets\">Related Website Sets</a>, you can declare a <code>primary</code> website and <code>associatedSites</code> for limited purposes to grant third-party cookie access and local storage for a limited number of sites.</p>\n<p>Chrome automatically recognizes related website sets declared, accepted, and maintained in this open-source GitHub repository: <a href=\"https://github.com/GoogleChrome/related-website-sets\">Related Website Sets</a></p>\n<p>It provides access through Storage Access API directly without prompting for user approval, but only after the user interacts with the relevant iframe.</p>\n<p>It is important to declare a limited number of domains in related website sets that are meaningful and used for specific purposes. Google may block or suspend any exploitative use of this feature.</p>\n<p>The top-level site can also request approval for specific cross-site resources and scripts to Storage Access API using <code>resuestStorageAccessFor()</code> API.</p>\n<p>If you’re using an external identity provider for your web application, you can declare the domain of the identity provider in the related set to ensure limited third-party cookies and storage access to the identity provider, thus ensuring seamless user authentication.</p>\n<p>Related Website Sets can also work to supplement third-party cookie restrictions in web SSO and federated SSO if the number of web applications (or domains) is limited.</p>\n<h3 id=\"federated-credential-management-fedcm-api\" style=\"position:relative;\"><a href=\"#federated-credential-management-fedcm-api\" aria-label=\"federated credential management fedcm api permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Federated Credential Management (FedCM) API</h3>\n<p>FedCM API enables federated SSO without third-party cookies.</p>\n<p>With FedCM API, a user follows these steps for authentication:</p>\n<ol>\n<li>The User navigates to a Service Provider (SP) — aka., Relying Party (RP)</li>\n<li>As the user requests to authenticate, the SP requests the browser through FedCM API to initiate authentication.</li>\n<li>The browser displays a list of available identity providers (supported by the RP), such as social IdPs like Google, Apple, LinkedIn, and Facebook, or other OAuth IdPs like LoginRadius.</li>\n<li>Once the user selects an IdP, the browser communicates with the IdP. Upon valid authentication, the IdP generates a secure token.\nThe browser delivers this secure token to the RP to facilitate user authorization.</li>\n</ol>\n<p>You can access a user demo of FedCM here: <a href=\"https://fedcm-rp-demo.glitch.me/\">FedCM</a>. </p>\n<p>For more information about implementing federated SSO with FedCM API, go through the <a href=\"https://developers.google.com/privacy-sandbox/3pcd/fedcm-developer-guide\">FedCM developer guide</a>.</p>\n<h2 id=\"how-is-loginradius-preparing-for-the-third-party-cookie-phase-out\" style=\"position:relative;\"><a href=\"#how-is-loginradius-preparing-for-the-third-party-cookie-phase-out\" aria-label=\"how is loginradius preparing for the third party cookie phase out permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>How is LoginRadius Preparing for the Third-party Cookie Phase-out?</h2>\n<p>Firstly, we’re committed to solving our customers' user identity pain points — and preparing for the third-party cookies phase-out is no different.</p>\n<p>We’ll implement the most relevant and widely useful solutions to facilitate a smooth transition for our customers.</p>\n<p>Please subscribe to our blog for more information. We’ll update you on how we help with the third-party cookie phase-out.</p>\n<h2 id=\"in-conclusion\" style=\"position:relative;\"><a href=\"#in-conclusion\" aria-label=\"in conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>In Conclusion</h2>\n<p>The proposed changes to phase out third-party cookies and suggested alternatives are evolving as Google has been actively collaborating and discussing changes with the border community.</p>\n<p>Moreover, browsers like Firefox, Safari, and Edge may approach restricting third-party cookies differently than Google does.</p>\n<p>From LoginRadius, we’ll keep you updated on what we’re doing as a leading Customer Identity and Access Management (CIAM) vendor to prepare for the third-party cookie phase-out.</p>\n<h2 id=\"glossary\" style=\"position:relative;\"><a href=\"#glossary\" aria-label=\"glossary permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Glossary</h2>\n<p><strong>Top-level site</strong>: It is the primary site a user has visited.</p>\n<p><strong>First-party cookie</strong>: A cookie set by the top-level site.</p>\n<p><strong>Third-party cookie</strong>: A cookie set by a domain other than the top-level site. For example, let’s assume that a user has visited <code>a.com</code>, which might use an embed from <code>loginradius.com</code> to facilitate authentication. If <code>loginradius.com</code> sets a cookie when the user visits <code>a.com</code>, it is called a third-party cookie as the user hasn’t directly visited <code>loginradius.com</code>.</p>\n<h2 id=\"references\" style=\"position:relative;\"><a href=\"#references\" aria-label=\"references permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>References</h2>\n<ul>\n<li><a href=\"https://developers.google.com/privacy-sandbox/3pcd/prepare/prepare-for-phaseout\">Changes to Chrome's treatment of third-party cookies</a></li>\n<li><a href=\"https://developers.google.com/privacy-sandbox/3pcd/guides/identity\">Check the impact of the third-party cookie changes on your sign-in workflows</a></li>\n</ul>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"July 08, 2024","updated_date":null,"description":"Google Chrome has planned to phase out third-party cookies, which will affect different website functionalities depending on third-party cookies. This blog focuses on how this phase-out affects identity and user authentication and discusses alternatives for overcoming challenges.","title":"How Chrome’s Third-Party Cookie Restrictions Affect User Authentication?","tags":["Identity","Cookies","Chrome"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/eb7396060c0adc430dbed2d04b63d431/ee604/third-party-cookies-phaseout-chrome.png","srcSet":"/static/eb7396060c0adc430dbed2d04b63d431/69585/third-party-cookies-phaseout-chrome.png 200w,\n/static/eb7396060c0adc430dbed2d04b63d431/497c6/third-party-cookies-phaseout-chrome.png 400w,\n/static/eb7396060c0adc430dbed2d04b63d431/ee604/third-party-cookies-phaseout-chrome.png 800w,\n/static/eb7396060c0adc430dbed2d04b63d431/f3583/third-party-cookies-phaseout-chrome.png 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Raghunath Reddy","github":"raghunath-r-a","avatar":null}}}},"pageContext":{"limit":6,"skip":270,"currentPage":46,"type":"//engineering//","numPages":52,"pinned":"17fa0d7b-34c8-51c4-b047-df5e2bbaeedb"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}