Implementation of Token Based Authentication

###What is token based authentication

Token-based authentication is a method to authenticate user access to the specific resources with a valid token that is generated by the server only if user provided a correct username and password.

###Steps to implement a simple token-based authentication example

a)    Create customer database
b)    Unique token generator
c)    Implements customer login operation
d)    Authentication

###Create a customer database

Create table customer  (
  customer_id int(11) not null AUTO_INCREMENT,
  username varchar(255) unique not null,
  password varchar(255) not null,
  token varchar(255),
  expired varchar(100),
  ip varchar(255),
  primary key (customer_id)
);

Add a customer:

Insert into customer(username, password) values("admin", "123456");

###Unique token generator

We need a method to generate unique token for different customers. The token is composed by three parts: machine id, timestamp and unique id.

//generate token
function generate_token(){
  $date = new DateTime();
  $token = $date->getTimestamp();
  //if we have multiple server, we need to assign different prefix to each one
  $token = uniqid('server1', true);       
 return $token;
}

###Customer login

<?php
  error_reporting(E_ALL);
  ini_set('display_errors', 1);

  //get username and password
  $username = $_POST['username'];
  $password = $_POST['password'];
  $ip = $_SERVER['REMOTE_ADDR'];

 //generate token
function generate_token(){
  $date = new DateTime();
  $token = $date->getTimestamp();
  $token = $token . uniqid('server1', true);       //if we have multiple server, we need to assign different prefix to each one
  return $token;
}

//connect database
try {
  $pdo = new PDO('mysql:host=localhost;dbname=project1', "project1", "0WkWy2dIHhcLfLKs");

  $sql = "select * from customer where username=:username and password=:password";
  $sth = $pdo->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
  $sth->execute(array(':username' => $username, ':password' => $password));
  $customer = $sth->fetchAll();

  if(count($customer) == 0){

    echo "username or password not correct";
    die();

  }else{

    $customer = $customer[0];
    $customer_id = $customer['customer_id'];
    $token = generate_token();

    //expired after 24 hours
    $date = new DateTime();
    $date->add(new DateInterval('PT24H'));

    $sql = "update customer set token=:token, ip=:ip, expired=:expired where customer_id=:customer_id";
    $sth = $pdo->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
    $sth->execute(
        array(
            ':token' => $token,
            ':ip' => $ip,
            ':expired' => $date->getTimestamp(),
            ':customer_id' => $customer_id
        )
    );

    echo "token : " . $token;
  }

  $dbh = null;
  } catch (PDOException $e) {
    print "Error!: " . $e->getMessage() . "<br/>";
    die();
}

###Authentication by token

<?php
  //check user token
  $token = $_POST['token'];
  $ip = $_SERVER['REMOTE_ADDR'];

 //current timestamp
 $date = new DateTime();
 $timestamp = $date->getTimestamp();

 //connect database
 try {
   $pdo = new PDO('mysql:host=localhost;dbname=project1', "project1", "0WkWy2dIHhcLfLKs");

   $sql = "select * from customer where token=:token and ip=:ip and expired > :timestamp";
   $sth = $pdo->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
   $sth->execute(array(':token' => $token, ':ip' => $ip, ':timestamp' => $timestamp));
   $customer = $sth->fetchAll();

   if(count($customer) == 0){

     echo "you haven't login system";
     die();

   } else {

     $customer = $customer[0];
     $username = $customer['username'];

     echo "you are : " . $username;
  }

} catch (PDOException $e) {
  print "Error!: " . $e->getMessage() . "<br/>";
  die();
}

By checking IP address and expired time, an illegal token can be prevented to access the system.