GPSlogger – serwer

Na stronę serwerową dla potrzeb eHomondo będą składać się: serwer LAMP (Linux, Apache2, MySQL, PHP), wystawionymi na świat portam 80 i 443, oraz przypisany do wybranej doment/poddomeny. Serwer warto utwardzić – receptura CIS Bemchmark, podobnie z samym Apache2 (mod_evasive, mod_security /aka WFA).

Jako warstwę odbierającą dane lokalizacyjne użytkowników, wykorzystamy PHP, nazwane tutaj(*) app.php oraz api.php (a także opisane js.php, jq.php etc…).

(*) tutaj w tym sensie, że w celu zabezpieczenia zmienię nazwy tych plików na losowe -zaś folder Apache2 zabezpieczę przed możliwością listowania. Nie jest to metoda odporna oczywiście w 100%, bo w przypadku podsłuchy nawy plików można wypatroszyć z treści, niemniej jednak jest pewnego rodzaju utrudnieniem.

Listowanie możemy wyłączyć np. dodając:

<Directory /var/www/mysite>
    Options -Indexes
</Directory>

Odbiór danych z aplikacji GPSlogger [app.php]

<?php
    // nagłówek odpowiedzi OK niezależnie od wszystkiego
    header("HTTP/1.1 200 OK");

    // proc. obsługi DB:
    include('/var/www/gpslogger/comm/db.php');
    $mdb = new Mdb();

    // sprawdzam, czy ten IP nie zbyt często (taki WFA): 
    $ipok = $mdb->ip_visited_not_so_offen();
    if(!$ipok) exit();

    $user_id = null;

    $method_id = null; // rodzaj urzadzenia/sposobu wysylki
    $uid = null;
    $lat = null;
    $lon = null;
    $time = null;
    $s = null;
    $alt = null;
    
    //uwierzytelnienie Basic-Auth z DB:
    if ( isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW']) ) {

        $auth_user0 = filter_var($_SERVER['PHP_AUTH_USER'], FILTER_SANITIZE_STRING);
        $auth_pw0 = filter_var($_SERVER['PHP_AUTH_PW'], FILTER_SANITIZE_STRING);
        list($uid, 
                $method_id) = $mdb->auth_user_pass($auth_user0, $auth_pw0);
    };    
    // wymagane dane
    if ( isset($_POST['lat']) && isset($_POST['lon']) 
            && isset($_POST['time']) && isset($_POST['s']) ) {
      
        $lat = filter_var($_POST['lat'], FILTER_VALIDATE_FLOAT);
        $lon = filter_var($_POST['lon'], FILTER_VALIDATE_FLOAT);
        $time_as_string = filter_var($_POST['time'], FILTER_SANITIZE_STRING);
        $dt_utc = gmdate("Y-m-d H:i:s", strtotime($time_as_string));
        $s = filter_var($_POST['s'], FILTER_SANITIZE_NUMBER_INT);
    }
    // opcjonalna dana
    if ( isset($_POST['alt']) )  {
        $alt = filter_var($_POST['alt'], FILTER_VALIDATE_FLOAT);
    }
    // gdy użytkownik uprawniony i dane niezbędne --> zaczynaj
    if($uid && $lat && $lon && $dt_utc) {

        $mdb->insert_new_gpspos_from_app(
                $method_id, $uid, 
                $lat, $lon, 
                $dt_utc
                );
    }

Niezależnie od wyniku, wyślemy odpowiedź o kodzie 200/ OK. Dalej sprawdzamy, czy requesty od tego nadawcy nie są zbyt częste -jeśli tak -ignorujemy, następnie sprawdzamy czy login i password jest znane, czy są wymagane dane wejściowe, oraz ew. opcjonalne.

Po tym wszystkim zapisujemy pozycję do DB. Jeśli pozycja jest identyczna jak poprzednia, to jedynie rozszerzamy okres czasu dla tej poprzedniej pozycji w DB -nie czyniąc nowego rekordu.

Dane z WEB-aplikacji [api.php]

api.php służy nie tylko jako backend do odbioru danych. Może również służyć jako serwer odpowiadający na zapytania o pewne dane.

<?php
include('/var/www/gpslogger/comm/db.php');
$mdb = new Mdb();
$str_json = file_get_contents('php:/ /input');
$ipok = $mdb->ip_visited_not_so_offen();
if(!$ipok) exit();
$data_in = json_decode($str_json);
$ask0 = $data_in->a;
$ask = filter_var($ask0, FILTER_SANITIZE_STRING);

$source = $data_in->s;

$method_id = filter_var($data_in->m, FILTER_SANITIZE_NUMBER_INT);

$token_from_cookie0 = $data_in->t;
$token_from_cookie = filter_var($token_from_cookie0, FILTER_SANITIZE_STRING);

$lon0 = $data_in->lon;
$lat0 = $data_in->lat;
$lon = filter_var($lon0, FILTER_VALIDATE_FLOAT);
$lat = filter_var($lat0, FILTER_VALIDATE_FLOAT);

$dt_from_utc = null;
$dt_to_utc = null;
$dt_from0 = $data_in->dtf;
if($dt_from0 != null) {
    $dt_from_utc = gmdate("Y-m-d H:i:s", strtotime($dt_from0));
}
$dt_to0 = $data_in->dtt;
if($dt_to0 != null) {
    $dt_to_utc = gmdate("Y-m-d H:i:s", strtotime($dt_to0));
}

$data_out = [];

if($token_from_cookie != null) {
    $user_id = $mdb->check_in_db($token_from_cookie);
    if($user_id != null) {
        
        // last_tokens
        $isok = $mdb->token_visited_not_so_offen($user_id);
        if(!$isok) exit();

        if($ask==null && $lon && $lat) {
            // wpis pozycji z apki
//            $now = date("Y.m.d H:i:s");
            $dt_utc = gmdate("Y.m.d H:i:s");
            $method_id = 2;
            if($source != 'pure_js') {
                $method_id = 3;
            }
            $mdb->save_gpspos_into_db($user_id, $lat, $lon, $dt_utc, $method_id);
            // dołączę jeszcze ostatnią pozycję z APP
            $last_apppos_row = $mdb->get_last_uid_fromapp_row(12/*$token_id*/);
            $dt_to = $last_apppos_row['dt_to'];
            if($dt_to == null) {
                $dt_to = $last_apppos_row['dt_from'];
            }
            // ten czas skalkuluj z prędkości:
            $time_repeat_seconds = 12; /* 9...301 */
            $data_out = [web=>[lat => $lat, 
                               lon => $lon, 
                               dt => date("Y.m.d H:i:s")],

                         app=>[lat => $last_apppos_row['lat'], 
                               lon => $last_apppos_row['lon'], 
                               dt => $dt_to],

                         time_repeat_seconds =>$time_repeat_seconds, /* 9...301 */
                        ];
        }
        /*elseif($ask== ... ) {
            
        }*/
        
        header('Content-Type: application/json');
        echo json_encode($data_out);
    }
}

w zależności od tego jaką wartość przybiera $ask – taką odpowiedź generuje api.php. Gdy $ask = null przychodząca pozycja GPS zostaje zapisana do DB.

Dodaj komentarz

Translate »