PHP Password Hashing API Tutorial

Learn how to use PHP 5.5’s password hashing API to store your user passwords more securely. A simple to use API that helps developers move towards bcrypt.

Are you hashing your user passwords? If not, you’re asking for trouble (just look at the recent password leaks). Keeping plain text passwords or using older, weaker algorithms like MD5 or SHA1 to store passwords have become outdated and less secure than newer, modern methods. For instance, with the release of PHP 5.5, you can use the new password hashing api.

Everybody knows that you should be hashing user passwords using bcrypt, but still a surprising number of developers uses insecure md5 or sha1 hashes. One of the reasons for this is that the crypt() API is ridiculously hard to use and very prone to programming mistakes.

PHP Password Hashing Functions

By adding a new, very simple to use API PHP hopes to move more developers towards bcrypt. It has four simple functions:

  • password_hash() – used to hash the password
  • password_verify() – used to verify a password against its hash
  • password_needs_rehash() – used when a password needs to be rehashed
  • password_get_info() – returns the name of the hashing algorithm and various options used while hashing

How to Hash Passwords Using PHP

Although the crypt() function is secure, it’s considered by many to be too complicated and prone to programmer error. Some developers then use a weak salt and weak algorithm for generating a hash instead, for example:

[code_highlight lang=”php”]$hash = md5($password . $salt); // works, but dangerous[/code_highlight]

But the password_hash() function can simplify our lives and our code can be secure. When you need to hash a password, just feed it to the function and it will return the hash which you can store in your database. Creating password hashes can’t be any simpler than this:

[code_highlight lang=”php”]$hash = password_hash( $password, PASSWORD_DEFAULT );[/code_highlight]

This will create a password hash using the default algorithm (currently bcrypt), the default load factor (currently 10) and an automatically generated salt. The used algorithm and salt will also be part of the resulting hash, so you don’t need to worry about them at all.

If you don’t want to stick with the defaults (which might change in the future), you can also provide algorithm and load factor yourself:

[code_highlight lang=”php”]$hash = password_hash( $password, PASSWORD_BCRYPT, [‘ cost’ => 12 ] );[/code_highlight]

That’s it! The first parameter is the password string that needs to be hashed and the second parameter specifies the algorithm that should be used for generating the hash.

The default algorithm is currently bcrypt, but a stronger algorithm may be added as the default later at some point in the future and may generate a larger string. If you are using PASSWORD_DEFAULT in your projects, be sure to store the hash in a column that’s capacity is beyond 60 characters. Setting the column size to 255 might be a good choice. You could also use PASSWORD_BCRYPT as the second parameter. In this case the result will always be 60 characters long.

The important thing here is that you don’t have to provide a salt value or a cost parameter. The new API will take care of all of that for you. And the salt is part of the hash, so you don’t have to store it separately. If you want to provide your own salt (or cost), you can do so by passing a third argument to the function, an array of options.

[code_highlight lang=”php”]$options = [
‘salt’ => custom_function_for_salt(), //write your own code to generate a suitable salt
‘cost’ => 12 // the default cost is 10
];
$hash = password_hash($password, PASSWORD_DEFAULT, $options);[/code_highlight]

In this way, you are always up-to-date with new security measures. If PHP later decides to implement a more powerful hashing algorithm your code can take advantage of it.

Verifying PHP Hashed Passwords

Now that you have seen how to generate hashes with the new API, let’s see how to verify a password. Remember that you store the hashes in a database, but it’s the plain password that you get when a user logs in.

The password_verify() function takes a plain password and the hashed string as its two arguments. It returns true if the hash matches the specified password. Verifying passwords is just as easy:

[code_highlight lang=”php”]// $password from user, $hash from database
if (password_verify($password, $hash)) {
// password valid!
} else {
// wrong password 🙁
}[/code_highlight]

Just remember that the salt is a part of the hashed password which is why we are not specifying it separately here.

Rehashing PHP Passwords

As time goes by you might want to change the password hashing algorithm or load factor, or PHP may change the defaults to be more secure. In this case new accounts should be created using the new options and existing passwords rehashed on login (you can do this only on login because you need the original password to do a rehash).

Doing this is also very simple:

[code_highlight lang=”php”]function password_verify_with_rehash( $password, $hash ) {
if ( ! password_verify( $password, $hash ) ) {
return false;
}

if ( password_needs_rehash( $hash, PASSWORD_DEFAULT ) ) {
$hash = password_hash( $password, PASSWORD_DEFAULT );

// update hash in database
}

return true;
}[/code_highlight]

The above snippet will keep your hashes up to date with the PHP default. But once again you can also specify custom options, e.g. password_needs_rehash($hash, PASSWORD_BCRYPT, ['cost' => 12']).

Retrieve PHP Hashed Password Info

Use password_get_info() to return an associative array with information about the given hash. When passed in a valid hash created by an algorithm supported by password_hash(), this function will return the following:

  • algo – a constant that identifies a particular algorithm
  • algoName – the name of the algorithm used
  • options – various options used while generating the hash

Compatibility for Older PHP Versions

The new API will only be introduced in PHP 5.5. Those who are using PHP 5.3.7 (or later) can use a library called password_compat which emulates the API and automatically disables itself once the PHP version is upgraded to 5.5.


Conclusion

The PHP password hashing API is definitely easier to work with than fumbling with the crypt() function. If your website is currently running on PHP 5.5, then I strongly recommended that you use the new hashing API. Learn more about the PHP password hashing API:

Facebook SDK PHP v4 & CodeIgniter

Trying to get the latest version of Facebook SDK for PHP (v4) working well with CodeIgniter? Me too! After doing a bunch of digging with a lot of trial and error, I finally figured it out. Learn how to build a library for CodeIgniter that will help bridge the gap between it and the Facebook SDK for PHP.

Trying to get the latest version of Facebook SDK for PHP (v4) working well with CodeIgniter? Me too! After doing a bunch of digging with a lot of trial and error, I finally figured it out. Learn how to build a library for CodeIgniter that will help bridge the gap between it and the Facebook SDK for PHP.

Step 1: Download & setup folders

The quickest & simplest way to install the Facebook SDK is via Composer. Installing is as easy as adding a require entry for the Facebook SDK for PHP to the composer.json file in the application directory:

application/composer.json

{
  "require" : {
    "facebook/php-sdk-v4" : "4.0.*"
  }
}

Navigate to the application directory and run composer install to download the required dependencies.

Step 2: Create & define config variables

You’ll also need to setup some config variables by creating a new config file:

application/config/facebook.php

$config['facebook']['api_id']       = 'YOUR APP ID';
$config['facebook']['app_secret']   = 'YOUR APP SECRET';
$config['facebook']['redirect_url'] = 'https://yourdomain.com/login';
$config['facebook']['permissions']  = array(
                                        'email',
                                        'user_location',
                                        'user_birthday'
                                      );

Open the application/config/autoload.php and add the Facebook config file you just created to the Auto-load Config files:

/*
| -------------------------------------------------------------------
|  Auto-load Config files
| -------------------------------------------------------------------
| Prototype:
|
|	$autoload['config'] = array('config1', 'config2');
|
| NOTE: This item is intended for use ONLY if you have created custom
| config files.  Otherwise, leave it blank.
|
*/

$autoload['config'] = array( 'facebook' );

Step 3: Create the Facebook CodeIgniter library

Create a new file called Facebook.php in the application/libraries directory.

This by no means is a complete library, but shows you how to use the API to create methods enabling you to access them in your controllers.

application/libraries/facebook/facebook.php:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

// Autoload the required files
require_once( APPPATH . 'vendor/facebook/php-sdk-v4/autoload.php' );

// Make sure to load the Facebook SDK for PHP via composer or manually

use Facebook\FacebookSession;
use Facebook\FacebookRedirectLoginHelper;
use Facebook\FacebookRequest;
// add other classes you plan to use, e.g.:
// use Facebook\FacebookRequest;
// use Facebook\GraphUser;
// use Facebook\FacebookRequestException;

class Facebook
{
  var $ci;
  var $session = false;

  public function __construct()
  {
    // Get CI object.
    $this->ci =& get_instance();

    // Initialize the SDK
    FacebookSession::setDefaultApplication( $this->ci->config->item('api_id', 'facebook'), $this->ci->config->item('app_secret', 'facebook') );
  }

  /**
   * Get FB session.
   */
  public function get_session()
  {
    if ( $this->ci->session->userdata('fb_token') ) {
      // Validate the access_token to make sure it's still valid
      $this->session = new FacebookSession( $this->ci->session->userdata('fb_token') );
      try {
        if ( ! $this->session->validate() ) {
          $this->session = false;
        }
      } catch ( Exception $e ) {
        // Catch any exceptions
        $this->session = false;
      }
    }
    else
    {
      // Add `use Facebook\FacebookRedirectLoginHelper;` to top of file
      $helper = new FacebookRedirectLoginHelper( $this->ci->config->item('redirect_url', 'facebook') );
      try {
        $this->session = $helper->getSessionFromRedirect();
      } catch( FacebookRequestException $ex ) {
        // When Facebook returns an error
        print_r($ex->getResponse());
        //redirect( base_url( 'login?err=' . $ex->getResponse() ) );
      } catch( \Exception $ex ) {
        print_r($ex->getResponse());
        // When validation fails or other local issues
        //redirect( base_url( 'login?err=' . $ex->getResponse() ) );
      }
    }
  }

  /**
   * Login functionality.
   */
  public function login()
  {
    $this->get_session();
    if ( $this->session )
    {
      $this->ci->session->set_userdata( 'fb_token', $this->session->getToken() );

      $user = $this->get_user();

      if ( $user && ! empty( $user['email'] ) )
      {
         $result = $this->ci->user_model->get_user( $user['email'] );

          if ( ! $result )
          {
            // Not registered.
            $this->ci->session->set_flashdata( 'fb_user', $user );
            redirect( base_url( 'register' ) );
          }
          else
          {
            if ( $this->ci->user_model->sign_in( $result->username, $result->password ) )
            {
              redirect( base_url( 'home' ) );
            }
            else
            {
              die( 'ERROR' );
              redirect( base_url( 'login' ) );
            }
          }
      }
      else
      {
        die( 'ERROR' );
      }
    }
  }

  /**
   * Returns the login URL.
   */
  public function login_url()
  {
    // Add `use Facebook\FacebookRedirectLoginHelper;` to top of file
    $helper = new FacebookRedirectLoginHelper( $this->ci->config->item('redirect_url', 'facebook') );

    return $helper->getLoginUrl( $this->ci->config->item('permissions', 'facebook') );
    // Use the login url on a link or button to
    // redirect to Facebook for authentication
  }

  /**
   * Returns the current user's info as an array.
   */
  public function get_user()
  {
    $this->get_session();
    if ( $this->session )
    {
      $request = ( new FacebookRequest( $this->session, 'GET', '/me' ) )->execute();
      $user    = $request->getGraphObject()->asArray();

      return $user;
    }
    return false;
  }

  /**
   * Get user's profile picture.
   */
  public function get_profile_pic( $user_id )
  {
    $this->get_session();
    if ( $this->session )
    {
      $request = ( new FacebookRequest( $this->session, 'GET', '/' . $user_id . '/picture?redirect=false&type=large' ) )->execute();
      $pic     = $request->getGraphObject()->asArray();

      if ( ! empty( $pic ) && ! $pic['is_silhouette'] ) {
        return $pic['url'];
      }
    }
    return false;
  }
}

The library above will give you access to the Facebook SDK Graph API. It creates and saves the Facebook token in session so you can access it later for calls to the API.


Example Usage

Once you’ve loaded the Facebook library you created above, you’ll have access to it within your controllers with the following:

For example, if you wanted to get the login URL (where user’s grant access):

Using the examples above, you should be able to add more methods to the library using the Graph API. If you need any help or run into any problems, drop me a comment below.


More on the Facebook SDK for PHP

Facebook PHP SDK v5.x (4.1) — a complete guide!

Facebook SDK PHP is a powerful library allowing you to retrieve user information, publish to profiles, enable Facebook registrations, logins and more. Learn how to easily implement the Facebook SDK PHP library (v4) with easy to follow examples to get your site integrated quickly.

Implement the Facebook SDK 5.x (4.1) for PHP to enable one-click registrations & logins, gain access to user photos, timelines and even publish to profiles.

Update (April 29, 2015): Facebook PHP SDK 5.x? What happened to 4.1 you ask? The Facebook PHP SDK will start following SemVer starting with v5.0. Before the decision to adopt SemVer, the official Facebook PHP SDK was going to be released as v4.1. But now v4.1 is just an alias to v5.0.0. So any references to 4.1 can be safely aliased to v5.0.0. For more information, see F8 2015 Facebook Developer Conference and the new PHP SDK.

Continue reading “Facebook PHP SDK v5.x (4.1) — a complete guide!”

Programmatically Create & Delete Image Styles in Drupal

Need to programmatically create or delete an image style in Drupal? Maybe you’re creating a module that needs to define a new style or looking to use an update handler to delete one. It’s a cinch to do with just a few lines of code.

I recently needed to delete a image style that was no longer being used with a update handler. Being that Drupal’s documentation is less than informative, I did some digging and finally figured it out. Check out how to create, flush and delete image styles below. Continue reading “Programmatically Create & Delete Image Styles in Drupal”

Drupal Custom Tokens: How to Easily Create Your Own

A feature I regularly use in WordPress development are shortcodes. I needed the same functionality in Drupal. Like most things I’ve found with Drupal, it’s not as easy or clear on how to go about it. No need to fret though, I’ll walk you through how to get ahead of the learning curve and easily create custom tokens.

A feature I regularly use in WordPress development are shortcodes. I needed the same functionality in Drupal. Like most things I’ve found with Drupal, it’s not as easy or clear on how to go about it. No need to fret though, I’ll walk you through how to get ahead of the learning curve and easily create custom tokens.

Drupal’s documentation — or lack of — and a lot of posts I found on how to create tokens had conflicting information. This was mainly due to portions of the Token module getting moved into the core beginning with D7. Though, it doesn’t due much good for typical users if there’s no interface or UI for defining custom tokens.

In the examples below, I’ll show you how to easily create custom tokens within a module.

Creating Custom Tokens in Drupal 7

To create custom tokens in D7, we’re going to use two hooks:

  • hook_token_info() – This is where you’ll create the token and define what they are.
  • hook_tokens() – This is where the magic happens, you’ll tell Drupal what to replace your tokens with.

Below, we’re going to create a custom token that holds the user’s session status (Logged In, Logged Out). You could use this token in conjunction with GA’s custom dimensions to gather more detailed analytics.

Step 1: Create & define the custom token.

In your module, add the following code:

The code above will return an associative array with your custom tokens data:

  • Name: The translated human-readable short name of the token.
  • Description: A translated longer description of the token.

It’s important to note the structure of the array: $info['tokens']['user']['session-status']. Where user is the token type, and session-status is the machine-friendly name.

If you have the Devel module installed, you can use dpm(token_get_info()) to view all available tokens and types.

Step 2: Replace the token.

In your module, after the code above, add the following:

That’s it! The session status token should now be available and appear in the list of tokens wherever tokens are available.

Helpful Drupal Token Modules

Here’s some helpful modules that will make working with tokens in Drupal easier:

  • Token – Provides a UI to view currently available tokens.
  • Token Filter – A very simple module to make token values available as an input filter.
  • Custom Tokens – Gives users the ability to create custom tokens for specific replacements.
  • Token Insert – Allows you to insert tokens into a textarea.

More Information on Drupal Tokens

PHP MySQL Connect, The Right Way!

Connecting to MySQL with PHP is a common among developers. Without a proper connection, your site performance and security could suffer. Learn how to setup & run queries with a PHP MySQL connection, the right way!

Connecting to MySQL with PHP is a common among developers. Without a proper connection, your site performance and security could suffer. Learn how to setup & run queries with a PHP MySQL connection, the right way!

PHP MySQL ConnectCode is a living text. All developers should be aware and embrace this fact. No matter the type of development you do, a year from now, there will probably be a better way to accomplish what you did today. Code is constantly evolving as technology improves—a perfect example being how to connect to MySQL with PHP.

I’ll walk you through how to properly connect to your MySQL databases with PHP for better site performance and security. Learn how to connect to MySQL with PHP the right way!

Connecting to MySQL with PHP

There’s many way to connect to MySQL with PHP. Some options include:

Which one is the best? Doing a quick Google search for ‘php mysql connect‘ will yield a ton of results with one common theme—connecting to MySQL with PHP should be done using a PDO connection. In the old days, most developers used mysql_connect to talk to their database. Code has evolved and that method has been officially deprecated as of PHP 5.5.0. You could use mysqli, but PDO is more stable with better performance and database support. There’s a great in-depth article by Dejan Marjanovic detailing the differences between PDO and MySQLi.

PDO MySQLi
Database support 12 different drivers MySQL only
API OOP OOP + procedural
Connection Easy Easy
Named parameters Yes No
Object mapping Yes Yes
Prepared statements (client side) Yes No
Performance Fast Fast
Stored procedures Yes Yes

PHP MySQL Connect with PDO

PDO – PHP Data Objects – is a database access layer providing a uniform method of access to multiple databases.

There’s a ton of articles out there about PDO, how it works, why to use it, and detailed information on it’s functions (see the bottom of this post for more information). Instead of going into all the intricacies, I’m just going to show you how to use it. So, let’s start off with the basics, how to use PDO to connect to MySQL.

Connecting with PDO

Depending on the type of database you’re using, there are slightly different connection methods. The example above uses MySQL. Here’s some other types of connection methods:

What if you run into errors? You should always wrap your PDO operations in a try/catch, and use the exception mechanism:

This will output any connection errors you might run into. It’s important to note, the default error mode for PDO is PDO::ERRMODE_SILENT. If you don’t spefify the mode, you’ll need to manually fetch errors after performing a query. PDO has three error modes, in the example above, where using ERRMODE_EXCEPTION. This is the mode you’re going to want to use in most situations. It’ll fire an exception allowing you to handle errors gracefully and hide data that might help someone exploit your system. Here’s the other two modes available:

Fetching Data with PDO

There’s a couple of different ways to run queries using PDO. Generally, it’s best to use prepared statements to safeguard against SQL injection. With the prepare method we prepare the query before the user’s data gets attached. See below:

For better readable code, it’s best to use named parameters vs. ?. Notice we used :name to specify the placeholder.

You could also use the bindParam:

Now, let’s look at how to get the output. Once you’ve called the execute method, there’s a variety of different ways to get your data: an array (the default), and object, etc. In the example above, we’re using the default PDO::FETCH_ASSOC to return an array. This can easily be overridden like so:

Here, we’re returning an anonymous object with property names that correspond to the columns. Other choices include, but not limited to:

  • PDO::FETCH_BOTH: Returns an array, indexed by both column-name, and 0-indexed
  • PDO::FETCH_BOUND: Returns TRUE and assigns the values of the columns in your result set to the PHP variables to which they were bound
  • PDO::FETCH_CLASS: Returns a new instance of the specified class

No results? No problem.

What if no results are returned? That’s the problem with the code above, we’re not providing any feedback if nothing is returned. We can easily fix that with the following:

Taking it a step further…

One of the benefits to using the PDO extension is the ability to execute the same SQL query multiple times with different parameters. Check out the example below:

The example above shows how you can easily execute the same query multiple times using different parameters. It’ll insert two rows, one with a name of “Ben”, and the other with “Angel”.

Creating, Updating, Deleting

Now that you’re connected, you’re probably going to want to run some queries. We looked into how to insert data above a little, now I’ll show you some more examples how to create, update and delete data:

Insert

Update

Delete

PDO Object Mapping

One of the coolest aspects of using PDO (mysqli can do this as well), is the ability to may query results to a class or object. See below:

Other Helpful Methods

Here’s some other helpful methods that will make life a lot easier when running queries with PDO:

Get last insert ID

lastInsertId() should always called on the database handle, not statement handle, and will return the auto incremented id of the last inserted row by that connection.

Return number of rows affected

The rowCount() method returns an integer indicating the number of rows affected by an operation. In at least one known version of PDO, according to this bug report the method does not work with select statements. If you’re having this problem, and can’t upgrade PHP, you could get the number of rows with the following:


More On PHP MySQL PDO Connections