Reply to thread

Okay,


I am ready for some criticism and feedback -


Here is my overall structure:


/ api / api.php

/ api / models / volunteer.php

/ api / security / authentication.php


Here is my Authentication File:

[CODE]$realm = 'API';

   

    $admins = array('REDACTED' => 'REDACTED', 'REDACTED2' => 'REDACTED2');


    // function to parse the http auth header

    function http_digest_parse($txt)

    {

        // protect against missing data

        $needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);

        $data = array();

        $keys = implode('|', array_keys($needed_parts));


        preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER);


        foreach ($matches as $m) {

            $data[$m[1]] = $m[3] ? $m[3] : $m[4];

            unset($needed_parts[$m[1]]);

        }


        return $needed_parts ? false : $data;

    }


    if (empty($_SERVER['PHP_AUTH_DIGEST'])) {

        header('HTTP/1.1 401 Unauthorized');

        header('WWW-Authenticate: Digest realm="'.$realm.

               '",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"');


        print "Sorry, you are not authorized to access this area";

        exit;

    }

   

    // analyze the PHP_AUTH_DIGEST variable

    if (!($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) || !isset($admins[$data['username']]))

    {

        header('HTTP/1.1 401 Unauthorized');

        header('WWW-Authenticate: Digest realm="'.$realm.

               '",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"');

        print "Sorry, you are not authorized to access this area";

        exit;

    }

   

    // generate the valid response

    $A1 = md5($data['username'] . ':' . $realm . ':' . $admins[$data['username']]);

    $A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);

    $valid_response = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);

   

    if ($data['response'] != $valid_response){

        header('HTTP/1.1 401 Unauthorized');

        header('WWW-Authenticate: Digest realm="'.$realm.

               '",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"');

        print "Sorry, you are not authorized to access this area";

        exit;

    }[/CODE]


The authentication works great, I am utilizing Postman as [USER=1]@RastaLulz[/USER] mentioned and it really helps to test the system!


Now for the API.php file:

[CODE]<?php

    //Require Authentication

    require_once 'security/authentication.php';

   

    header('Content-Type: application/json'); //Set return type to JSON

    define('IN_INDEX', 1); //Define access to allow global.php to be referenced

   

    //Include Global File

    include_once '../../global.php'; //Access global.php, which will give access to the engine which has the MySQL connection

   

    //Declare Global Variables

    global $engine; //Define engine from the global file

   

    //Include Model Files

    include_once 'models/volunteer.php'; //Include our volunteer model, which will give the blueprint / class for what a volunteer is

   

    //Declare Model Variables

    $volunteer = new Volunteer($engine); //Define an instance of our volunteer

   

    //Get the type of request, current working on just GET requests

    $reqType = '';


    if(isset($_GET['type'])){

        $reqType = $_GET['type'];

    }else{

        header('HTTP/1.1 400 Bad Request');

        print "Must Define Type Parameter";

        exit;

    }


    switch(strtoupper($reqType)){

        case "GET":

        {

            HandleGET(); //We established we want to GET, we can call this function to handle our GET options

        }

        break;

   

        case "POST":

        {

            HandlePOST();

        }

        break;

       

        default:

        {

            header('HTTP/1.1 404 Not Found');

            print "The requested Type is not supported";

            exit;

        }

        break;

    }

   

    function HandleGET(){

        global $volunteer; //Get access to our blueprint class

       

       //What is the action we want to GET

        $action = '';

       

        if(isset($_GET['action'])){

            $action = $_GET['action'];

        }else{

            header('HTTP/1.1 400 Bad Request');

            print "Must Define Action Parameter";

            exit;

        }

       

        switch(strtoupper($action)){

            case "VOLUNTEERS": //Sample for returning all of the volunteers in the system

            {

                //Volunteer Query

                $result = $volunteer->read();

               

                $num = mysqli_num_rows($result);

               

                //Check Volunteers Exist

                if($num > 0){

                    // Volunteer Array

                    $volunteers_arr = array();

                    $volunteers_arr['data'] = array();

                   

                    while($row = mysqli_fetch_array($result)){

                        extract($row);

                        $volunteer_item = array(

                            'id' => $ID,

                            'fname' => $fname,

                            'lname' => $lname,

                            'email' => $email,

                            'phone' => $phone,

                            'created' => $created

                        );

                       

                        //Push to "data" results

                        array_push($volunteers_arr['data'], $volunteer_item);

                    }

                   

                    //Turn result array to JSON

                    echo json_encode($volunteers_arr);

                }else{

                    //No Posts

                    echo json_encode(

                        array('message' => 'No Volunteers Found')

                    );

                }

            }

            break;

            default:

            {

                header('HTTP/1.1 404 Not Found');

                print "The requested Action is not supported";

                exit;

            }

            break;

        }

    }

   

    function HandlePOST(){

        global $volunteer;

       

    }

?>[/CODE]



And here is my basic volunteer model class:

[CODE]<?php

class Volunteer{

    private $engine;

    private $table = 'volunteers';

   

    //Post Properties

    public $ID;

    public $firstname;

    public $lastname;

    public $email;

    public $phone;

    public $account_create;

   

    // Constructor with DB

    public function __construct($dbEngine){

        $this->engine = $dbEngine;

    }

   

    // Get Volunteers

    public function read(){

        //Create Query

        $query = 'SELECT

              vol.ID as ID,

              vol.firstname as fname,

              vol.lastname as lname,

              vol.email as email,

              vol.phone as phone,

              vol.account_created as created

            FROM

              ' . $this->table . ' vol

            ORDER BY

              vol.account_created DESC';

       

        //Fetch Results

        $results = $this->engine->query($query);

       

        return $results;

    }

}

?>[/CODE]

[automerge]1607790736[/automerge]

Just going to bump this, as I am on a time frame and want to know if this is following best practices or if I should change how I am implementing this...


Top