Toon posts:

[PHP/SQL] Web service weigert POST request [rest api]

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Om een REST API te bouwen, heb ik volgende tutorial gevolgd: http://coenraets.org/blog...p-and-the-slim-framework/

Kort samengevat: Door middel van een Slim framework wordt een Restful web service opgebouwd die een inventaris maakt van verschillende wijnen. De API wordt gebruikt icm een front end met jQuery, waar je wijnen kunt selecteren etc.

De GET en DELETE functies werken zonder problemen, alleen krijg ik de POST "addWine" en PUT "updateWine" niet werkend. Oftewel wordt er helemaal geen wijn product toegevoegd, ofwel zijn alle velden NULL, ofwel krijg ik een andere error (o.a. Fatal error: Cannot redeclare class Slim).

Acties die ik reeds ondernomen heb:
- de meegeleverde jQuery client gebruik ik niet, geen interesse in. De auteur gebruikt ook nog cURL, ik gebruik een REST extensie voor Chrome waar ik al eerder mee gewerkt heb
- Zowel lokaal als hosted de API getest, geen verschil
- (lokaal) Configuratie Wampserver is correct,

De tutorial stamt uit 2011, dus wie weet lag het daar aan...
- (hosted) verschillende PHP versies geprobeerd, geen verschil
- latere versies van het Slim framework geprobeerd zonder resultaat

- In de functies addWine() en updateWine() heb ik: Slim::getInstance()->request(); vervangen door \Slim\Slim::getInstance()->request();
- op regel 5 vervolgens $app = new Slim(); vervangen door $app = new \Slim\Slim();

Wie kan me op het juiste pad helpen?

Acties:
  • 0 Henk 'm!

  • Tsjilp
  • Registratie: November 2002
  • Niet online

Tsjilp

RS[I]ds

Stuur je data als JSON naar de server (met bij behorende JSON header)? Dan herkent PHP dat niet als POST request en moet je de data inhalen middels
PHP:
1
$data = json_decode(file_get_contents('php://input'));

Raar... Is zo gek nog niet


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Met deze functie:


PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function addWine() {
    $request = Slim::getInstance()->request();
    $wine = json_decode($request->getBody());
    $sql = "INSERT INTO wine (name, grapes, country, region, year, description) VALUES (:name, :grapes, :country, :region, :year, :description)";
    try {
        $db = getConnection();
        $stmt = $db->prepare($sql);  
        $stmt->bindParam("name", $wine->name);
        $stmt->bindParam("grapes", $wine->grapes);
        $stmt->bindParam("country", $wine->country);
        $stmt->bindParam("region", $wine->region);
        $stmt->bindParam("year", $wine->year);
        $stmt->bindParam("description", $wine->description);
        $stmt->execute();
        $wine->id = $db->lastInsertId();
        $db = null;
        echo json_encode($wine); 
    } catch(PDOException $e) {
        echo '{"error":{"text":'. $e->getMessage() .'}}'; 
    }
}


...wordt de request volgens mij wel herkend, want het resultaat van de request komt ook in de database terecht, maar de velden zijn wel allemaal NULL.

JSON:
1
2
3
4
5
6
7
8
9
{
name: null
grapes: null
country: null
region: null
year: null
description: null
id: "46"
}


Vast iets kleins waar ik overheen kijk, maar met mijn geringe ervaring kom ik er gewoon niet uit.

Acties:
  • 0 Henk 'm!

  • Merethil
  • Registratie: December 2008
  • Laatst online: 16-10 06:58
Verwijderd schreef op maandag 18 augustus 2014 @ 11:41:
Met deze functie:


PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function addWine() {
    $request = Slim::getInstance()->request();
    $wine = json_decode($request->getBody());
    $sql = "INSERT INTO wine (name, grapes, country, region, year, description) VALUES (:name, :grapes, :country, :region, :year, :description)";
    try {
        $db = getConnection();
        $stmt = $db->prepare($sql);  
        $stmt->bindParam("name", $wine->name);
        $stmt->bindParam("grapes", $wine->grapes);
        $stmt->bindParam("country", $wine->country);
        $stmt->bindParam("region", $wine->region);
        $stmt->bindParam("year", $wine->year);
        $stmt->bindParam("description", $wine->description);
        $stmt->execute();
        $wine->id = $db->lastInsertId();
        $db = null;
        echo json_encode($wine); 
    } catch(PDOException $e) {
        echo '{"error":{"text":'. $e->getMessage() .'}}'; 
    }
}


...wordt de request volgens mij wel herkend, want het resultaat van de request komt ook in de database terecht, maar de velden zijn wel allemaal NULL.

JSON:
1
2
3
4
5
6
7
8
9
{
name: null
grapes: null
country: null
region: null
year: null
description: null
id: "46"
}


Vast iets kleins waar ik overheen kijk, maar met mijn geringe ervaring kom ik er gewoon niet uit.
var_dump je $wine eens op regel 3 (of log 'm naar een file ofzo, zodat je kan zien wat erin gaat).
Ik gok dat 'ie 'm gewoon niet goed kan uitlezen.

Volgens http://php.net/manual/en/pdostatement.execute.php , example 1, bind je trouwens je waarden met deze placeholder: ":[placeholder]" (dus met dubbele punt erin) ipv met "[placeholder]".

[ Voor 5% gewijzigd door Merethil op 18-08-2014 11:50 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
var_dump geeft 'null'.

De dubbele punt toevoegen verandert niks...

Acties:
  • 0 Henk 'm!

  • Merethil
  • Registratie: December 2008
  • Laatst online: 16-10 06:58
Verwijderd schreef op maandag 18 augustus 2014 @ 13:01:
var_dump geeft 'null'.

De dubbele punt toevoegen verandert niks...
Dus je Json wordt niet goed decoded op regel 3, want er wordt niets in je $wine gezet.
Hoe ziet je Json eruit?

Sterker nog: Zit er wel iets in je $request op regel 2?

[ Voor 9% gewijzigd door Merethil op 18-08-2014 13:04 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Wijn met ID 5:

JSON:
1
2
3
4
5
6
7
8
9
{
id: "5"
name: "REX HILL"
year: "2009"
grapes: "Pinot Noir"
country: "USA"
region: "Oregon"
description: "One cannot doubt that this will be the wine served at the Hollywood award shows, because it has undeniable star power. Be the first to catch the debut that everyone will be talking about tomorrow."
}


GET /wines met alle wijnen op een rij levert ook normale JSON op.

Mijn vermoeden is dat het in de request al mis gaat inderdaad. Moet haast wel iets met Slim te maken hebben. De documentatie van Slim is echter nogal.. slim.

De tutorial ik probeer te volgen, is al uit 2011. In de reacties zijn er nog een aantal die hetzelfde probleem hebben (NULL velden bij addWine). Wellicht is er in die drie jaar gewoon iets veranderd in Slim waardoor de voorgestelde API in de tutorial nu niet meer kan werken.

Zoals gezegd, mijn ervaring met REST en Slim is nog te beperkt om hier de oorzaak te kunnen vinden. Dus wellicht moet ik gewoon op zoek naar een ander voorbeeld, al is de kwaliteit van de meeste niet zo best.

Tenzij jij (of een andere Tweaker) nog een helder idee heeft om dit op te lossen, dan hoor ik het uiteraard graag. Anders verspil ik niet langer jullie tijd :)

[ Voor 31% gewijzigd door Verwijderd op 18-08-2014 13:26 ]


Acties:
  • 0 Henk 'm!

  • Merethil
  • Registratie: December 2008
  • Laatst online: 16-10 06:58
Wat gebeurt er als je het omzet naar deze variant?
http://docs.slimframework.com/#Request-Body

Of heb je de Slim Framework installer gebruikt die bij de tutorial zat? Want zo te zien is er sowieso een verandering in syntax.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik heb de versie gebruikt die bij de tutorial zat. De recentste versie ook, maar dan vliegen de errors helemaal in de rondte.

Acties:
  • 0 Henk 'm!

  • Tsjilp
  • Registratie: November 2002
  • Niet online

Tsjilp

RS[I]ds

Misschien moet je die errors dan even posten?

Raar... Is zo gek nog niet


Acties:
  • 0 Henk 'm!

  • jd2210
  • Registratie: Februari 2015
  • Laatst online: 05-04-2022
Hoi,

Misschien een erg late reactie op een oude post maar misschien heb je er nog wat aan voor je toekomstige projecten.

Ik heb even wat oude code opgedoken wat ik heb geschreven om bekend te raken met restservices en met angular.js

dit stukje is uit de backend en bevat de functies voor het slim framework:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
 
<?php

require 'Slim/Slim.php';

$app = new Slim();
$app->get('/login/:username/:password','getLogin');
$app->get('/users', 'getUsers');
$app->get('/users/:id', 'getUser');
$app->post('/register', 'Register');
$app->post('/reactie/:id','postReactie');


$app->run();


function getLogin($username,$password){  
    $request = Slim::getInstance()->request();
    $user = json_decode($request->getBody());
    $sql= 'SELECT * FROM users WHERE Username="'.$username.'" AND Wachtwoord = "'.$password.'"';
    try {
        $db = getConnection();
        $stmt = $db->query($sql);  
        $wines = $stmt->fetchAll(PDO::FETCH_OBJ);
        $db = null;
        echo json_encode($wines); 
    } catch(PDOException $e) {
        echo '{"error":{"text":'. $e->getMessage() .'}}'; 
    }
}


function getUsers() {
    $sql = "select * FROM users ORDER BY userID";
    try {
        $db = getConnection();
        $stmt = $db->query($sql);  
        $wines = $stmt->fetchAll(PDO::FETCH_OBJ);
        $db = null;
        echo json_encode($wines);
    } catch(PDOException $e) {
        echo '{"error":{"text":'. $e->getMessage() .'}}'; 
    }
}

function getUser($id) {
    $sql = "select * FROM users WHERE UserID=".$id." ORDER BY UserID";
    try {
        $db = getConnection();
        $stmt = $db->query($sql);  
        $wines = $stmt->fetchAll(PDO::FETCH_OBJ);
        $db = null;
        echo json_encode($wines);
    } catch(PDOException $e) {
        echo '{"error":{"text":'. $e->getMessage() .'}}'; 
    }
}

function Register() {
    $request = Slim::getInstance()->request();
    $user = json_decode($request->getBody());

    $sql = "INSERT INTO users (Naam,Achternaam,Beroep,Username,Wachtwoord) VALUES (:naam, :achternaam, :beroep, :username, :wachtwoord)";
    try {
        $db = getConnection();
        $stmt = $db->prepare($sql);  
        $stmt->bindParam("naam", $user->naam);
        $stmt->bindParam("achternaam", $user->achternaam);
        $stmt->bindParam("beroep", $user->beroep);
        $stmt->bindParam("username", $user->username);
        $stmt->bindParam("wachtwoord", $user->wachtwoord);
        $stmt->execute();
        $user->id = $db->lastInsertId();
        $db = null;
        echo json_encode($user); 
    } catch(PDOException $e) {
        echo '{"error":{"text":'. $e->getMessage() .'}}'; 
    }
}

function postReactie($id){
    $request = Slim::getInstance()->request();
    $message = json_decode($request->getBody());
    $sql ="INSERT INTO news (userid,newsitem) VALUES(".$id.",:text)";
    try{
        $db = getConnection();
        $stmt = $db->prepare($sql);  
        $stmt->bindParam("text", $message->text);
        $stmt->execute();
        //$user->id = $db->lastInsertId();
        $db = null;
        echo json_encode($message); 
    } catch(PDOException $e) {
        echo '{"error":{"text":'. $e->getMessage() .'}}'; 
    }
        
    }




function getConnection() {
    $dbhost="localhost";
    $dbuser="root";
    $dbpass="";
    $dbname="spabook";
    $dbh = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);  
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    return $dbh;
}
?>


indien je er behoefte aan hebt kan ik wellicht kijken of ik ook nog de voorkant die de api aanspreekt kan opduiken.

Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Aan degene die dit wil overnemen: fix de SQL injection bij getLogin & getUser wel even ;)

Acties:
  • 0 Henk 'm!

  • orf
  • Registratie: Augustus 2005
  • Laatst online: 21:59

orf

En gebruik geen plain text voor wachtwoorden. Gebruik een cryptografische hashing methode

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
En geef in je API niet direct PDO fouten terug. :Z En gebruik dan ook echt overal json_encode()

etc etc...

{signature}


Acties:
  • 0 Henk 'm!

  • jd2210
  • Registratie: Februari 2015
  • Laatst online: 05-04-2022
Oke ik had inderdaad erbij moeten vermelden dat het om code ging die niet op het internet terecht zou komen en daar ook niet voor bedoelt is/was.

vannuit security standpunt zou ik dan ook meegeven om:

Hashing te gebruiken samen met salting.
Indien mogelijk het liefst variabele salting zodat je salt niet altijd hetzelfde is.
Altijd prepared statements te gebruiken(voor php is dit PDO).
Je SQL gebruiker alleen de rechten geven voor de database waarvoor hij wordt gebruikt en alleen rechten geven voor de gebruikte statements.
Error reporting en het teruggeven van SQL errors uitzetten.
Geen zwakke hashing methode als md5 gebruiken.
Als je aan hash iteraties doet bedenk je dan dat er voor alle woorden al rainbowtables zijn t/m 4 iteraties voor alle hashes.

en wanneer je echt paranoïde bent gebruik 2 traps verificatie.

Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
jd2210 schreef op dinsdag 10 februari 2015 @ 15:29:
Oke ik had inderdaad erbij moeten vermelden dat het om code ging die niet op het internet terecht zou komen en daar ook niet voor bedoelt is/was.
Geen excuus wat mij betreft, beveiliging moet altijd in orde zijn. Voor opslaan van passwords ook geen custom dingen gaan doen, pak gewoon bcrypt of scrypt.

Acties:
  • 0 Henk 'm!

  • Spinal
  • Registratie: Februari 2001
  • Laatst online: 29-09 15:25
Voor PHP 5.5 en hoger: password_hash en password_verify

Full-stack webdeveloper in Groningen

Pagina: 1