{"id":3465,"date":"2026-08-27T18:36:52","date_gmt":"2026-08-27T23:36:52","guid":{"rendered":"https:\/\/xlinesoft.com\/blog\/?p=3465"},"modified":"2026-08-28T12:48:40","modified_gmt":"2026-08-28T17:48:40","slug":"how-to-add-user-impersonation-to-a-phprunner-application","status":"publish","type":"post","link":"https:\/\/xlinesoft.com\/blog\/2026\/08\/27\/how-to-add-user-impersonation-to-a-phprunner-application\/","title":{"rendered":"How to Add User Impersonation to a PHPRunner Application"},"content":{"rendered":"<p>PHPRunner&#8217;s Security API lets an administrator switch to another application user without knowing that user&#8217;s password. This is useful when an administrator needs to reproduce a problem using the same pages, permissions, and data access as the user.<\/p>\n<p>In this tutorial we will add an impersonation button to the login table, switch accounts with <strong>Security::loginAs()<\/strong>, display a warning banner while impersonation is active, and provide a link that restores the original administrator session.<\/p>\n<p><a href=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2026\/08\/impersonation_banner.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2026\/08\/impersonation_banner-1024x661.png\" alt=\"\" width=\"810\" height=\"523\" class=\"alignnone size-large wp-image-3468\" srcset=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2026\/08\/impersonation_banner-1024x661.png 1024w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2026\/08\/impersonation_banner-600x387.png 600w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2026\/08\/impersonation_banner-768x496.png 768w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2026\/08\/impersonation_banner.png 1122w\" sizes=\"auto, (max-width: 810px) 100vw, 810px\" \/><\/a><\/p>\n<p>We will cover:<\/p>\n<p>1. Preparing the login table and administrator group<br \/>\n2. Adding an impersonation button to the List page<br \/>\n3. Showing the button only to administrators<br \/>\n4. Switching to the selected user<br \/>\n5. Redirecting after impersonation<br \/>\n6. Adding an impersonation banner<br \/>\n7. Styling the banner<br \/>\n8. Returning to the administrator session<\/p>\n<p><!--more--><\/p>\n<h3>1. Preparing the login table and administrator group<\/h3>\n<p>This tutorial assumes that database authentication and user group permissions are already configured in PHPRunner. The table used for authentication must also be included in the project and have a List page that administrators can open.<\/p>\n<p>The sample project uses <strong>first_name<\/strong> as the username field. Replace <strong>first_name<\/strong> in the code below if your login table uses another field.<\/p>\n<p>We will also use <strong>Administrators<\/strong> as the administrator group name. Replace it with the group name used in your project.<\/p>\n<h3>2. Adding the impersonation button to the List page<\/h3>\n<p>Open the login table&#8217;s List page in Page Designer and switch to Advanced Grid. Select a grid cell, then use <strong>Insert \u2192 Custom button \u2192 New button<\/strong>.<\/p>\n<p>Set the button label to &#8216;Login as this user&#8217; and place it inside the grid row. Select the button and set its <strong>Item ID<\/strong> to:<br \/>\n&#8216;login_as_user&#8217;<\/p>\n<p>The Item ID is important. It is the value used by <strong>hideItem()<\/strong> in the next step. You can select the button in Page Designer and find its Item ID in the properties panel on the right.<\/p>\n<p><a href=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2026\/08\/Login_as_user.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2026\/08\/Login_as_user-1024x580.png\" alt=\"\" width=\"810\" height=\"459\" class=\"alignnone size-large wp-image-3470\" srcset=\"https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2026\/08\/Login_as_user-1024x580.png 1024w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2026\/08\/Login_as_user-600x340.png 600w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2026\/08\/Login_as_user-768x435.png 768w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2026\/08\/Login_as_user-1536x871.png 1536w, https:\/\/xlinesoft.com\/blog\/wp-content\/uploads\/2026\/08\/Login_as_user.png 1708w\" sizes=\"auto, (max-width: 810px) 100vw, 810px\" \/><\/a><\/p>\n<h3>3. Showing the button only to administrators<\/h3>\n<p>Open <strong>Events \u2192 login table \u2192 List page \u2192 After record processed<\/strong> and add the following PHP code:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"php\" name=\"mshighlighter\" >\r\nif (\r\n    Security::getUserGroup() != $_SESSION[\"AdminGroupName\"]\r\n    || $data[\"first_name\"] == Security::getUserName()\r\n) {\r\n    $pageObject->hideItem(\"login_as_user\", $recordId);\r\n}<\/textarea><\/pre>\n<\/div>\n<p>The second argument of <strong>hideItem()<\/strong> is required because the button is located inside a List page grid row. The code hides the button from non-administrators and also hides it on the administrator&#8217;s own record.<\/p>\n<h3>4. Switching to the selected user<\/h3>\n<p>Open the custom button code and select its <strong>Server<\/strong> tab. Add the following PHP code:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"php\" name=\"mshighlighter\" >\r\nif (Security::getUserGroup() != $_SESSION[\"AdminGroupName\"]) {\r\n    $result[\"success\"] = false;\r\n    return;\r\n}\r\n\r\n$record = $button->getCurrentRecord();\r\n\r\n$_SESSION[\"impersonation_admin\"] = Security::getUserName();\r\n\r\nSecurity::loginAs($record[\"first_name\"]);\r\n\r\n$result[\"success\"] = true;<\/textarea><\/pre>\n<\/div>\n<p>The group is checked again on the server so that hiding the button is not the only protection. The original administrator username is saved before <strong>Security::loginAs()<\/strong> replaces the current login session.<\/p>\n<h3>5. Redirecting after impersonation<\/h3>\n<p>In the same custom button, open the <strong>Client After<\/strong> tab and add this JavaScript code:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"javascript\" name=\"mshighlighter\" >\r\nif (result[\"success\"]) {\r\n    window.location.href = \"menu.php\";\r\n}<\/textarea><\/pre>\n<\/div>\n<p>The redirect reloads the application menu using the impersonated user&#8217;s permissions.<\/p>\n<h3>6. Adding the impersonation banner<\/h3>\n<p>Proceed to <strong>Style Editor \u2192 Templates \u2192 header.htm<\/strong>. Add the following code to the common project header:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"php\" name=\"mshighlighter\" >\r\n<?php\r\nif (\r\n    Security::isLoggedIn()\r\n    &#038;&#038; !empty($_SESSION[\"impersonation_admin\"])\r\n) {\r\n    $adminUsername = htmlspecialchars(\r\n        $_SESSION[\"impersonation_admin\"],\r\n        ENT_QUOTES,\r\n        \"UTF-8\"\r\n    );\r\n\r\n    $currentUsername = htmlspecialchars(\r\n        Security::getUserName(),\r\n        ENT_QUOTES,\r\n        \"UTF-8\"\r\n    );\r\n?>\r\n<div id=\"impersonation-banner\">\r\n    <span>\r\n        <strong>Impersonation mode:<\/strong>\r\n        Admin <strong><?php echo $adminUsername; ?><\/strong>\r\n        is browsing as\r\n        <strong><?php echo $currentUsername; ?><\/strong>.\r\n    <\/span>\r\n\r\n    <a href=\"menu.php?return_admin=1\">\r\n        Return to admin session\r\n    <\/a>\r\n<\/div>\r\n\r\n<script>\r\n(function () {\r\n    var banner = document.getElementById(\"impersonation-banner\");\r\n\r\n    if (!banner || !document.body) {\r\n        return;\r\n    }\r\n\r\n    document.body.insertBefore(banner, document.body.firstChild);\r\n    document.body.classList.add(\"impersonation-active\");\r\n})();\r\n<\/script>\r\n<?php\r\n}\r\n?><\/textarea><\/pre>\n<\/div>\n<p>The banner appears on every generated page while an administrator is impersonating another logged-in user. The usernames are escaped before they are inserted into the page.<\/p>\n<h3>7. Styling the banner<\/h3>\n<p>Open <strong>Style Editor \u2192 Modify CSS<\/strong> and add the following project-level Custom CSS:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"\" name=\"mshighlighter\" >\r\n:root {\r\n    --impersonation-banner-height: 40px;\r\n}\r\n\r\n#impersonation-banner {\r\n    position: sticky !important;\r\n    top: 0 !important;\r\n    z-index: 1000000 !important;\r\n    width: 100% !important;\r\n    max-width: none !important;\r\n    height: var(--impersonation-banner-height);\r\n    box-sizing: border-box;\r\n    margin: 0 !important;\r\n    padding: 0 16px;\r\n    display: flex;\r\n    align-items: center;\r\n    justify-content: center;\r\n    gap: 18px;\r\n    background: #fff3cd;\r\n    border-bottom: 1px solid #e0bd64;\r\n    color: #664d03;\r\n    font-size: 14px;\r\n    line-height: 20px;\r\n    text-align: center;\r\n    white-space: nowrap;\r\n}\r\n\r\n#impersonation-banner a {\r\n    color: #664d03;\r\n    font-weight: 600;\r\n    text-decoration: underline;\r\n}\r\n\r\nbody.impersonation-active .r-topheader[data-fixed] {\r\n    top: var(--impersonation-banner-height) !important;\r\n}\r\n\r\nbody.impersonation-active .r-left[data-fixed] {\r\n    top: var(--impersonation-banner-height) !important;\r\n    height: calc(100vh - var(--impersonation-banner-height)) !important;\r\n}\r\n\r\nbody.impersonation-active > .r-vbar-page,\r\nbody.impersonation-active > .r-topbar-page {\r\n    min-height: calc(100vh - var(--impersonation-banner-height));\r\n}\r\n\r\n@media print {\r\n    #impersonation-banner {\r\n        display: none !important;\r\n    }\r\n\r\n    body.impersonation-active .r-topheader[data-fixed],\r\n    body.impersonation-active .r-left[data-fixed] {\r\n        top: 0 !important;\r\n    }\r\n}<\/textarea><\/pre>\n<\/div>\n<p>Besides styling the warning, this CSS moves PHPRunner&#8217;s fixed navigation elements below the banner.<\/p>\n<h3>8. Returning to the administrator session<\/h3>\n<p>Open <strong>Events \u2192 Global events \u2192 After App Init<\/strong> and add the following PHP code:<\/p>\n<div class=\"my-syntax-highlighter\">\n<pre><textarea id=\"mshighlighter\" class=\"mshighlighter\" language=\"php\" name=\"mshighlighter\" >\r\n$_SESSION[\"AdminGroupName\"] = \"Administrators\";\r\n\r\nif (\r\n    isset($_GET[\"return_admin\"])\r\n    && !empty($_SESSION[\"impersonation_admin\"])\r\n) {\r\n    $adminUsername = $_SESSION[\"impersonation_admin\"];\r\n\r\n    unset($_SESSION[\"impersonation_admin\"]);\r\n\r\n    Security::loginAs($adminUsername);\r\n\r\n    header(\"Location: menu.php\");\r\n    exit();\r\n}<\/textarea><\/pre>\n<\/div>\n<p>The event defines the administrator group used by the other events. When the return link is clicked, it restores the saved administrator username, removes the impersonation marker, and redirects back to the menu.<\/p>\n<p>After rebuilding the project, log in as an administrator and open the login table&#8217;s List page. Click &#8216;Login as this user&#8217; beside another account. PHPRunner will apply that user&#8217;s identity and permissions, display the impersonation banner, and allow you to return to the original administrator session.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Learn how to let administrators impersonate application users in PHPRunner, display a clear warning banner, and return safely to the original session.<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[95,1],"tags":[],"class_list":["post-3465","post","type-post","status-publish","format-standard","hentry","category-css","category-php-category"],"_links":{"self":[{"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/posts\/3465","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/comments?post=3465"}],"version-history":[{"count":6,"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/posts\/3465\/revisions"}],"predecessor-version":[{"id":3473,"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/posts\/3465\/revisions\/3473"}],"wp:attachment":[{"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/media?parent=3465"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/categories?post=3465"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/xlinesoft.com\/blog\/wp-json\/wp\/v2\/tags?post=3465"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}