Using authentication modes

HTTP and cookie authentication modes are recommended in a multi-user environment where you want to give users access to their own database and don't want them to play around with others. Nevertheless, be aware that MS Internet Explorer seems to be really buggy about cookies, at least till version 6. Even in a single-user environment, you might prefer to use HTTP or cookie mode so that your user/password pair are not in clear in the configuration file.

HTTP and cookie authentication modes are more secure: the MySQL login information does not need to be set in the phpMyAdmin configuration file (except possibly for the $cfg['Servers'][$i]['controluser']). However, keep in mind that the password travels in plain text unless you are using the HTTPS protocol. In cookie mode, the password is stored, encrypted with the AES algorithm, in a temporary cookie.

Then each of the true users should be granted a set of privileges on a set of particular databases. Normally you shouldn't give global privileges to an ordinary user unless you understand the impact of those privileges (for example, you are creating a superuser). For example, to grant the user real_user with all privileges on the database user_base:

GRANT ALL PRIVILEGES ON user_base.* TO 'real_user'@localhost IDENTIFIED BY 'real_password'; 

What the user may now do is controlled entirely by the MySQL user management system. With HTTP or cookie authentication mode, you don't need to fill the user/password fields inside the $cfg['Servers'].

See also

1.32 Can I use HTTP authentication with IIS?, 1.35 Can I use HTTP authentication with Apache CGI?, 4.1 I'm an ISP. Can I setup one central copy of phpMyAdmin or do I need to install it for each customer?, 4.2 What's the preferred way of making phpMyAdmin secure against evil access?, 4.3 I get errors about not being able to include a file in /lang or in /libraries.

HTTP authentication mode

Note

There is no way to do proper logout in HTTP authentication, most browsers will remember credentials until there is no different successful authentication. Because of this, this method has a limitation that you can not login with the same user after logout.

Signon authentication mode

The very basic example of saving credentials in a session is available as examples/signon.php:

<?php /**  * Single signon for phpMyAdmin  *  * This is just example how to use session based single signon with  * phpMyAdmin, it is not intended to be perfect code and look, only  * shows how you can integrate this functionality in your application.  *  * @package    PhpMyAdmin  * @subpackage Example  */ declare(strict_types=1);  /* Use cookies for session */ ini_set('session.use_cookies', 'true'); /* Change this to true if using phpMyAdmin over https */ $secure_cookie = false; /* Need to have cookie visible from parent directory */ session_set_cookie_params(0, '/', '', $secure_cookie, true); /* Create signon session */ $session_name = 'SignonSession'; session_name($session_name); // Uncomment and change the following line to match your $cfg['SessionSavePath'] //session_save_path('/foobar'); @session_start();  /* Was data posted? */ if (isset($_POST['user'])) {     /* Store there credentials */     $_SESSION['PMA_single_signon_user'] = $_POST['user'];     $_SESSION['PMA_single_signon_password'] = $_POST['password'];     $_SESSION['PMA_single_signon_host'] = $_POST['host'];     $_SESSION['PMA_single_signon_port'] = $_POST['port'];     /* Update another field of server configuration */     $_SESSION['PMA_single_signon_cfgupdate'] = ['verbose' => 'Signon test'];     $id = session_id();     /* Close that session */     @session_write_close();     /* Redirect to phpMyAdmin (should use absolute URL here!) */     header('Location: ../index.php'); } else {     /* Show simple form */     header('Content-Type: text/html; charset=utf-8');     echo '<?xml version="1.0" encoding="utf-8"?>' , "\n";     ?>     <!DOCTYPE HTML>     <html lang="en" dir="ltr">     <head>     <link rel="icon" href="../favicon.ico" type="image/x-icon">     <link rel="shortcut icon" href="../favicon.ico" type="image/x-icon">     <meta charset="utf-8">     <title>phpMyAdmin single signon example</title>     </head>     <body>     <?php     if (isset($_SESSION['PMA_single_signon_error_message'])) {         echo '<p class="error">';         echo $_SESSION['PMA_single_signon_error_message'];         echo '</p>';     }     ?>     <form action="signon.php" method="post">     Username: <input type="text" name="user"><br>     Password: <input type="password" name="password"><br>     Host: (will use the one from config.inc.php by default)     <input type="text" name="host"><br>     Port: (will use the one from config.inc.php by default)     <input type="text" name="port"><br>     <input type="submit">     </form>     </body>     </html>     <?php } ?> 

Alternatively, you can also use this way to integrate with OpenID as shown in examples/openid.php:

<?php /**  * Single signon for phpMyAdmin using OpenID  *  * This is just example how to use single signon with phpMyAdmin, it is  * not intended to be perfect code and look, only shows how you can  * integrate this functionality in your application.  *  * It uses OpenID pear package, see https://pear.php.net/package/OpenID  *  * User first authenticates using OpenID and based on content of $AUTH_MAP  * the login information is passed to phpMyAdmin in session data.  *  * @package    PhpMyAdmin  * @subpackage Example  */ declare(strict_types=1);  if (false === @include_once 'OpenID/RelyingParty.php') {     exit; }  /* Change this to true if using phpMyAdmin over https */ $secure_cookie = false;  /**  * Map of authenticated users to MySQL user/password pairs.  */ $AUTH_MAP = [     'https://launchpad.net/~username' => [         'user' => 'root',         'password' => '',     ], ];  /**  * Simple function to show HTML page with given content.  *  * @param string $contents Content to include in page  *  * @return void  */ function Show_page($contents) {     header('Content-Type: text/html; charset=utf-8');     echo '<?xml version="1.0" encoding="utf-8"?>' , "\n";     ?>     <!DOCTYPE HTML>     <html lang="en" dir="ltr">     <head>     <link rel="icon" href="../favicon.ico" type="image/x-icon">     <link rel="shortcut icon" href="../favicon.ico" type="image/x-icon">     <meta charset="utf-8">     <title>phpMyAdmin OpenID signon example</title>     </head>     <body>     <?php     if (isset($_SESSION['PMA_single_signon_error_message'])) {         echo '<p class="error">' , $_SESSION['PMA_single_signon_message'] , '</p>';         unset($_SESSION['PMA_single_signon_message']);     }     echo $contents;     ?>     </body>     </html>     <?php }  /**  * Display error and exit  *  * @param Exception $e Exception object  *  * @return void  */ function Die_error($e) {     $contents = "<div class='relyingparty_results'>\n";     $contents .= '<pre>' . htmlspecialchars($e->getMessage()) . "</pre>\n";     $contents .= "</div class='relyingparty_results'>";     Show_page($contents);     exit; }   /* Need to have cookie visible from parent directory */ session_set_cookie_params(0, '/', '', $secure_cookie, true); /* Create signon session */ $session_name = 'SignonSession'; session_name($session_name); @session_start();  // Determine realm and return_to $base = 'http'; if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {     $base .= 's'; } $base .= '://' . $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT'];  $realm = $base . '/'; $returnTo = $base . dirname($_SERVER['PHP_SELF']); if ($returnTo[strlen($returnTo) - 1] != '/') {     $returnTo .= '/'; } $returnTo .= 'openid.php';  /* Display form */ if (! count($_GET) && ! count($_POST) || isset($_GET['phpMyAdmin'])) {     /* Show simple form */     $content = '<form action="openid.php" method="post"> OpenID: <input type="text" name="identifier"><br> <input type="submit" name="start"> </form> </body> </html>';     Show_page($content);     exit; }  /* Grab identifier */ if (isset($_POST['identifier']) && is_string($_POST['identifier'])) {     $identifier = $_POST['identifier']; } elseif (isset($_SESSION['identifier']) && is_string($_SESSION['identifier'])) {     $identifier = $_SESSION['identifier']; } else {     $identifier = null; }  /* Create OpenID object */ try {     $o = new OpenID_RelyingParty($returnTo, $realm, $identifier); } catch (Exception $e) {     Die_error($e); }  /* Redirect to OpenID provider */ if (isset($_POST['start'])) {     try {         $authRequest = $o->prepare();     } catch (Exception $e) {         Die_error($e);     }      $url = $authRequest->getAuthorizeURL();      header('Location: ' . $url);     exit; } else {     /* Grab query string */     if (! count($_POST)) {         list(, $queryString) = explode('?', $_SERVER['REQUEST_URI']);     } else {         // I hate php sometimes         $queryString = file_get_contents('php://input');     }      /* Check reply */     try {         $message = new OpenID_Message($queryString, OpenID_Message::FORMAT_HTTP);     } catch (Exception $e) {         Die_error($e);     }      $id = $message->get('openid.claimed_id');      if (! empty($id) && isset($AUTH_MAP[$id])) {         $_SESSION['PMA_single_signon_user'] = $AUTH_MAP[$id]['user'];         $_SESSION['PMA_single_signon_password'] = $AUTH_MAP[$id]['password'];         session_write_close();         /* Redirect to phpMyAdmin (should use absolute URL here!) */         header('Location: ../index.php');     } else {         Show_page('<p>User not allowed!</p>');         exit;     } } 

If you intend to pass the credentials using some other means than, you have to implement wrapper in PHP to get that data and set it to $cfg['Servers'][$i]['SignonScript']. There is a very minimal example in examples/signon-script.php:

<?php /**  * Single signon for phpMyAdmin  *  * This is just example how to use script based single signon with  * phpMyAdmin, it is not intended to be perfect code and look, only  * shows how you can integrate this functionality in your application.  *  * @package    PhpMyAdmin  * @subpackage Example  */ declare(strict_types=1);  /**  * This function returns username and password.  *  * It can optionally use configured username as parameter.  *  * @param string $user User name  *  * @return array  */ function get_login_credentials($user) {     /* Optionally we can use passed username */     if (! empty($user)) {         return [             $user,             'password',         ];     }      /* Here we would retrieve the credentials */     return [         'root',         '',     ]; } 

Config authentication mode