Du bist nicht angemeldet. [Anmelden]
Optionen
Thema bewerten
[MySQL] Connector - #2884039 - 09.01.2018, 11:51:19
Bizarrus
​Bizzi is activated.

Registriert: 29.07.2006
Beiträge: 2.551
Ort: Dortmund
Ich habe einen kleinen MySQL-Connector geschrieben, sofern man nicht dauernd eine separate API schreiben möchte. Die MySQL-Verbindung wird über einer HTTP(S)-Schnittstelle getunnelt und liefert direkte Ergebnisse.

Das ganze ist nur für erfahrene Nutzer gedacht, zumal die Schnittstelle auf die schnelle geschrieben wurde, die SQL-Queries direkt ausgeführt und nicht gefiltert werden.

Man kann das ganze sicherlich auch noch verschönern, in dem man extra Methoden für SELECT, UPDATE, DELETE oder whatever bereitstellt, der die Eingaben dann auch gegen SQL-Injections filtert.

In der UserApp wird der Connector wie folgt verwendet:
classes/MySQL.js
Code:
const MySQL = (new function MySQL() {
	let _server = {
		tunnel:		null,
		hostname:	'localhost',
		port:		3306,
		username:	'root',
		password:	null,
		database:	null
	};
	
	this.setConnection = function setConnection(tunnel, hostname, port, username, password, database) {
		_server.tunnel		= tunnel;
		_server.hostname	= hostname;
		_server.port		= port;
		_server.username	= username;
		_server.password	= password;
		_server.database	= database;
	};
	
	this.call = function call(data, callback) {
		KnuddelsServer.getExternalServerAccess().postURL(_server.tunnel, {
			data: data,
			onSuccess: function onSuccess(responseData, externalServerResponse) {
				callback(responseData);
			},
			onFailure: function(responseData, externalServerResponse) {
				callback(responseData);
			}
		});
	};
	
	this.query = function query(statement, callback) {
		this.call({
			action:		'query',
			hostname:	_server.hostname,
			port:		_server.port,
			username:	_server.username,
			password:	_server.password,
			database:	_server.database,
			query:		statement
		}, callback);
	};
}());


main.js
Code:
// MySQL-Klasse wird in die App geladen
require('classes/MySQL.js');

var App = (new function AppContainer() {
	this.onAppStart = function onAppStart() {
		// Setzen der Verbindungsinformationen (HTTPS wird empfohlen!)
		// MySQL.setConnection(tunnel, hostname, port, username, password, database);
		MySQL.setConnection('https://deineDomain.tld/MySQL.php', 'localhost', 3306, 'root', '*****', 'database');
	};
}());


Von nun an kannst du überall in der App MySQL-Queries abfragen:
Zitat:

MySQL.query('SELECT * FROM `yourTable` WHERE `id`=9 LIMIT 1', function onCallback(result) {
// Mache mit den Results das, was du möchtest,.. wir geben diese einfach per /p Nachricht aus.
user.sendPrivateMessage(result);
});


Auf deinem WebSpace oder auch Server musst du nur noch die MySQL.php bereitstellen:
Code:
<?php
	$response			= (object) null;
	$response->time		= time();
	$response->error	= false;
	header('Content-Type: text/plain; charset=x-user-defined');
	error_reporting(E_ALL);
	ini_set('display_errors', 'On');
	set_time_limit(0);
	
	if(!isset($_POST['action']) || !isset($_POST['hostname']) || !isset($_POST['port']) || !isset($_POST['username']) || !isset($_POST['password']) || !isset($_POST['database'])) {
		$response->error	= true;
		$response->message	= 'Invalid Parameter';
		print json_encode($response);
		exit();
	}
	
	try {
		$connection = new PDO(sprintf('mysql:host=%s;port=%d;dbname=%s', $_POST['hostname'], $_POST['port'], $_POST['database']), $_POST['username'], $_POST['password'], [
			PDO::MYSQL_ATTR_INIT_COMMAND	=> 'SET NAMES utf8',
			PDO::ATTR_ERRMODE				=> PDO::ERRMODE_EXCEPTION
		]);
	} catch(PDOException $e) {
		$response->error	= true;
		$response->message	= $e->getMessage();
		print json_encode($response);
		exit();
	}
	
	switch($_POST['action']) {
		case 'query':
			try {
				$stmt = $connection->prepare($_POST['query']);
				$stmt->execute();
				$response->response	= $stmt->fetchAll(PDO::FETCH_OBJ);
			} catch(PDOException $e) {
				$response->error	= true;
				$response->response	= $e;
			}
		break;
	}
	
	print json_encode($response);
?>


Have fun!
_________________________
Bot.public('I love °>features/james-exchange/ft_james-exchange_surprised.gif<>James|/w "<°');

[zum Seitenanfang]  
Re: [MySQL] Connector [Re: Bizarrus] - #2884041 - 09.01.2018, 12:21:01
Bizarrus
​Bizzi is activated.

Registriert: 29.07.2006
Beiträge: 2.551
Ort: Dortmund
Das ganze steht nun auch auf GitHub zur Verfügung: https://github.com/Bizarrus/MySQL-Connector

Vielleicht werde ich das ganze im Verlaufe der Projektplanung eines Freundes noch weiter ausbauen :-)
_________________________
Bot.public('I love °>features/james-exchange/ft_james-exchange_surprised.gif<>James|/w "<°');

[zum Seitenanfang]  
Re: [MySQL] Connector [Re: Bizarrus] - #2884102 - 09.01.2018, 17:56:28
Sephiroth ME
​gods own prototype

Registriert: 24.11.2003
Beiträge: 213
Ort: RLP, DE
Die Idee an sich ist super.

Die Umsetzung leider nicht so gut, die Benutzerdaten sollten Serverseitig (in PHP selbst) gespeichert werden und die API Mittels einer Benutzerliste oder "allowedApps"-Liste (aus der Datenbank selbst) abgefragt werden. - Spart Traffic und verhindert dass die Passwörter jemals übertragen/mitgeschnitten werden können.
Die Informationen von der App, welche Anfragt sind immer vorhanden in den Headerdaten, wenn sie von Knuddels kommen. Zudem kann man die Server selbst ($_SERVER['REMOTE_ADDR']) auch auf eine Whitelist setzen.

So wie es aktuell ist, würde ich von der Benutzung abraten, es nimmt einem zwar viel arbeit ab, aber mit den Limits die Knuddels für die UserApps hat, lohnt es sich leider kaum. - Traurig aber wahr. :(

In 99% der Fälle greift man sowieso auf die lokale Datenbank zu, von daher kann man da die Datenbankdaten auch in PHP direkt speichern, spart Traffic und das Query kann am Ende länger sein bei dem ohnehin schon niedrigen 10K Limit für ausgehende abfragen. - Ich hab im produktiven Bereich teilweise Querys die weit über dieses Limit gehen, für mich wäre es also ungeeignet.

MfG :)
_________________________
one step closer to world domination

[zum Seitenanfang]  
Re: [MySQL] Connector [Re: Sephiroth ME] - #2884135 - 09.01.2018, 19:40:35
Bizarrus
​Bizzi is activated.

Registriert: 29.07.2006
Beiträge: 2.551
Ort: Dortmund
Zitat:
Die Umsetzung leider nicht so gut, die Benutzerdaten sollten Serverseitig (in PHP selbst) gespeichert werden

Das Konzept kann jeder Zeit angepasst werden. Es gibt vielleicht auch Fälle, in dem ein Nutzer diverse andere Datenbanken nutzen möchte, die nicht gerade lokal genutzt werden. Selbst PDO kannst du einfach via SQLite austauschen oder was du gerade benötigst.

Zitat:
[...] verhindert dass die Passwörter jemals übertragen/mitgeschnitten werden können

Insbesondere wenn die Daten verschlüsselt sind. Auch wenn du hier in einer gewissen Form Recht hast, aber Passwörter werden über all verwendet, ob du die nun in der App mit verschlüsselter SSL/HTTPS-Verbindung überträgst oder es direkt in der PHP einbaust, was weitere Sicherheitslücken eröffnet, bleibt jedem selbst überlassen.

Selbst wenn du die Header-Daten abfragst/validierst, die lassen sich selbst mit einfachem cURL-Request faken, im Gegenzug zu einem IP-Spoofing. Dann hast du eine offene Schnittstelle, die trotzdem jeder "nutzen" kann.

Zitat:
aber mit den Limits die Knuddels für die UserApps hat, lohnt es sich leider kaum

Dies ist ja auch die Idee dahinter, insbesondere wenn man komplexe Datenstrukturen haben möchte. Wenn du die Liomits der ExternalServerAccess meinst: Man sollte natürlich auch nicht jede 500ms Abfragen tätigen. Wer Daten nachläd macht sich zuvor ohnehin Gedanken, ab wann Daten mit einem externen Server synchronisiert werden.

Zitat:
Ich hab im produktiven Bereich teilweise Querys die weit über dieses Limit gehen, für mich wäre es also ungeeignet.

Dann mache dir einmal Gedanken zum Queuebased bzw. chunked transfer, damit du zwar die maximale Kapazität pro Request zwar ausschöpfst, aber Häppchenweise holst...
_________________________
Bot.public('I love °>features/james-exchange/ft_james-exchange_surprised.gif<>James|/w "<°');

[zum Seitenanfang]  
Re: [MySQL] Connector [Re: Bizarrus] - #2884145 - 09.01.2018, 20:15:25
Sephiroth ME
​gods own prototype

Registriert: 24.11.2003
Beiträge: 213
Ort: RLP, DE
Ja, die Entscheidung, was man nutzt ist immer schwierig. Man kann fast alles fälschen und missbrauchen.

Es ist aber leichter die Apps, welche Zugriff haben an einer Stelle zu speichern und zu verwalten, als jeder App dies direkt zu erlauben, wenn nur die EntwicklerID z. B. hinterlegt ist in der KnuddelAccess.txt.

Die PHP File würde ja im aktuellen Zustand überhaupt nichts berücksichtigen, was die UserApps oder die Nutzung allgemein angeht und erlaubt so wie sie aktuell ist für alle direkt Zugriff. Stichwort Bruteforce - Und wer benennt schon root oder Administrator in der Datenbank um? - das vergessen auch viele.

Wäre zugriff aufs Lokale Dateisystem gegeben (also KnuddelsServer), könnte man so einfach direkt SQLLite oder einfaches INI-Datei/ReadFile nutzen. Allerdings würden UserApps (mit Schreibzugriff ins Dateisystem) dann zu unüberschaubar werden, lesender Zugriff würde schon genügen.

Chunks als Ergebnis zurückgeben ist nicht das Problem, es ist auch bitter nötig bei solchen Requests, die Anfrage selbst aufsplitten ist hingegen mehr als nervig. - Was wenn eine der Teilabfragen zwischendrin mal nicht klappt, man muss sie dann nochmal senden. Jede Eventualität muss da auch berücksichtigt werden.

Mein einzige Gedanke ist da gerade eigentlich nur noch "Scheiß übertriebene Limits.". Ohne Datenbanken kann man nicht wirklich vernünftig arbeiten und die Persistenz ist nicht für spezielle Abfragen ausgelegt wie es SQL kann.

ESA ist dafür aber auch nicht wirklich geeignet. :(
_________________________
one step closer to world domination

[zum Seitenanfang]  
Re: [MySQL] Connector [Re: Sephiroth ME] - #2884205 - 10.01.2018, 00:36:08
Bizarrus
​Bizzi is activated.

Registriert: 29.07.2006
Beiträge: 2.551
Ort: Dortmund
Ich habe das ganze nun einmal bearbeitet und etwas besser abgesichert. Es gibt nun API-Methoden und eine Config um diverse Einstellungen zu machen.

Sicherheitseinstellungen in der Config ermöglichen es, das aufrufen der API zu verhindern. Die meisten Einstellungen (sogar App und Channelbegrenzungen) sind in der knuddelsAccess.txt möglich!

Das ganze ist nun unter https://github.com/Bizarrus/UserApps-API verfügbar.

Ich werde morgen dafür eine komplette Dokumentation schreiben.

Die Datenbankfunktionalität sollte als Hilfe angesehen werden. Zum Beispiel ein ausschließliches vorladen der Daten bei AppStart.
_________________________
Bot.public('I love °>features/james-exchange/ft_james-exchange_surprised.gif<>James|/w "<°');

[zum Seitenanfang]  
Re: [MySQL] Connector [Re: Bizarrus] - #2884207 - 10.01.2018, 01:05:28
Sephiroth ME
​gods own prototype

Registriert: 24.11.2003
Beiträge: 213
Ort: RLP, DE
Antwort auf: Bizarrus
...
Das ganze ist nun unter https://github.com/Bizarrus/UserApps-API verfügbar.

Ich werde morgen dafür eine komplette Dokumentation schreiben.

Die Datenbankfunktionalität sollte als Hilfe angesehen werden. Zum Beispiel ein ausschließliches vorladen der Daten bei AppStart.

Bis auf den kleinen Fauxpax in der config.php, bin ich gespannt. :-D
_________________________
one step closer to world domination

[zum Seitenanfang]  
Re: [MySQL] Connector [Re: Sephiroth ME] - #2884211 - 10.01.2018, 07:25:18
Vampiric Desire
​ChannelMaster

Registriert: 15.09.2013
Beiträge: 1.689
Zitat:
define('ALLOWEDED_DEVELOPERS', true);



Es gibt kein ALLOWEDED... nur ALLOWED wäre richtig.

Erstmal interessanter Ansatz, leider dient es wirklich nur für einmalige Abfragen und/oder seltenen.
Daher stellt sich die Frage, ob es hier sinnvoll ist und man nicht selber eine kleine 'API' schreibt komplett Serverseitig. Ich glaube letzteres empfinde ich für sinnvoller - aber das muss jedem selber überlassen sein.

Wenn man schon mit prepare arbeitet, bietet es sich auch an mit bindValue statt mit einem sprintf Hack zu arbeiten - zumal wenn ich das richtig sehe du den tablename auch nicht absicherst? kann es aber übersehen haben.


Wichtig wäre es, wenn du die Limits über ExternalServerAccess beachtest und dokumentierst. Ansonsten schöne Arbeit.
_________________________
/apps install 30559674.ChannelMaster

[zum Seitenanfang]  
Re: [MySQL] Connector [Re: Vampiric Desire] - #2884297 - 10.01.2018, 16:44:19
Bizarrus
​Bizzi is activated.

Registriert: 29.07.2006
Beiträge: 2.551
Ort: Dortmund
Zitat:

Es gibt kein ALLOWEDED... nur ALLOWED wäre richtig.

Ist ein kleiner Typo-Fail von mir :-D Das kommt, wenn jemand dich nebenbei anquatscht :-D Dann kopiert man die Konstanten und ändert nur den letzteren Teil ab,... :D Werde ich gleich korrigieren.

Prepare oder Bind ist im Prinzip egal, ich habe mit Absicht named keys genommen statt mit soliden Fragezeichen beim binding zu arbeiten. Besonders wenn du größere Statements hast, ist es mit named parametern einfacher zu debuggen.

Zitat:
leider dient es wirklich nur für einmalige Abfragen und/oder seltenen.

Wer entwickeln kann, insbesondere auf Performance achtet, wird damit ohnehin sparsam umgehen und nur dann Datenbankabfragen durchführen, wenn diese benötigt werden. Ich habe bereits oben schon erwähnt, dass man damit versuchen sollte sparsam umzugehen.
_________________________
Bot.public('I love °>features/james-exchange/ft_james-exchange_surprised.gif<>James|/w "<°');

[zum Seitenanfang]  
Re: [MySQL] Connector [Re: Bizarrus] - #2884322 - 10.01.2018, 19:17:12
Bizarrus
​Bizzi is activated.

Registriert: 29.07.2006
Beiträge: 2.551
Ort: Dortmund
Ich habe nun das ganze auch gut Dokumentiert, inklusiver Beispiele :-)

https://github.com/Bizarrus/UserApps-API/tree/master
https://github.com/Bizarrus/UserApps-API/wiki
_________________________
Bot.public('I love °>features/james-exchange/ft_james-exchange_surprised.gif<>James|/w "<°');

[zum Seitenanfang]