Jump to content
Unity Insider Forum
MustafGames

SQLite Abfrage Speziel

Recommended Posts

Hallo,

 

ich bin gerade dabei mit der SQLite Datenbank etwas zu arbeiten, da ich davon noch nicht viel Ahnung habe möchte ich an einen Beispiel etwas ausprobieren.

 

Ich habe eine Tabelle (Players) mit 2 Feldern (Name und Passwort), bisher sind 2 Spieler registriert, wenn ich jetzt ein Login System mache, möchte ich überprüfen ob zu den eingegeben Spielernamen ein Eintrag in der Tabelle ist, wenn ja soll dann das Passwort verglichen werden.

 

Welche Befehle für die query muss ich dafür nehmen?

 

Freu mich auf eure Antworten.

Share this post


Link to post
Share on other sites

Ich kenn mich mit sqlite nicht aus, aber dafür kann ich ein bisschen sql^^

Falls eine Query wirklich nur aus einem String besteht sollte das hier funktionieren

 

"SELECT Name, Passwort FROM Players p WHERE p.Name = NameVomSpieler AND p.Passwort = PasswortVomSpieler"

Share this post


Link to post
Share on other sites

Ich kenn mich mit sqlite nicht aus, aber dafür kann ich ein bisschen sql^^

Falls eine Query wirklich nur aus einem String besteht sollte das hier funktionieren

 

"SELECT Name, Passwort FROM Players p WHERE p.Name = NameVomSpieler AND p.Passwort = PasswortVomSpieler"

 

Danke, ich bin leider nicht mehr in der Oberschule weil da hatten wie sowas in einfacher Form in Informatik :D

 

In deiner Methode, wird ja gleich mit abgefragt ob ein Benutzername mit den Passwort besteht, kann man das dann noch als Nachricht ausgeben wenn kein Spieler mit diesen Passwort existiert oder anders rum?

Share this post


Link to post
Share on other sites

Keine Ahnung.

DIe Query muss doch irgendwas zurückgeben, schau doch einfach mal nach was da zurück kommt und prüfe 2 Möglichkeiten:

 

1. Name und Passwort existieren

2. Name oder Passwort existiert nicht

Share this post


Link to post
Share on other sites

SELECT COUNT(*) FROM Players WHERE Name = NameVomSpieler AND Passwort = PasswortVomSpieler

 

Die Query sollte dir dann die Anzahl der gefunden Einträge zurückgeben, sollte also eigentlich zwischen 0 und 1 liegen, würde aber überprüfen ob die Anzahl über 1 ist.

 

Außerdem solltest du mit "mysql_real_escape_string()" arbeiten.

 

Hoffe konnte dir helfen.^^

 

#Edit: Ist echt lange her als ich mit sql gearbeitet hab, könnte also falsch sein.

Share this post


Link to post
Share on other sites

In deiner Methode, wird ja gleich mit abgefragt ob ein Benutzername mit den Passwort besteht, kann man das dann noch als Nachricht ausgeben wenn kein Spieler mit diesen Passwort existiert oder anders rum?

Select 'Passwort' from Players Where 'Name' = NameDesSpielers

 

Das gibt dir das Passwort des Spielers zurück, kriegst du null weißt du, dass der Spieler nicht existiert bzw es den Namen nicht gibt. (da nicht kein Eintrag dazu gefunden wurde)

Kriegst du ein Ergebnis ungleich null kannst du das Passwort mit dem übermittelten Passwort vergleichen, ist es ungleich weißt du, dass der Spieler existiert, der Nutzer aber das falsche Passwort eingegeben hat.

Ist es gleich, kannst du den Spieler einloggen.

 

In jedem Fall kannst du dann dem Spieler die passende Nachricht übermitteln.

Könnte Syntaktisch falsch sein, ich hab nich so viel Erfahrung mit SQLite ^^

Ich glaube mich erinnern zu können, dass Attribute immer in Hochkommas stehen müssen? Keine Ahnung.. Das Vorgehen dürfte aber ersichtlich sein ^^

 

Benutzt du da eig Php?

Könntest dir ja überlegen ob du einen ORMapper benutzen möchtest, finde ich persönlich schöner als sich mit Php und SQL rumschlagen zu müssen, sofern du nicht mega optimierte, customizedte Riesenbefehle in die Datenbank absetzen willst.

Share this post


Link to post
Share on other sites

@Tiwaz: nein das mit dem Hochkommas bei den Attributen ist falsch..

Hochkommas brauchst du nur wenn du Spalten anders bezeichnen möchtest im Select:

Select Passwort as 'mein PW' from Players where Name='NameDesSpielers'

 

Generell gefällt mir aber die Variante von IBGKDennisI besser, da es auch den Fall abdeckt, wenn mehr als ein Passwort zurückkommt. Und ich persönlich bekomme lieber 0 als null zurück.

 

 

Also mein Weg wäre wie folgt:

1) Prüfe ob der Benutzer in der DB ist:

SELECT COUNT(*) FROM Players p WHERE p.Name = NameVomSpieler

 

 

2) Wenn eins zurück kommt:

SELECT COUNT(*) FROM Players p WHERE p.Name = NameVomSpieler AND p.Passwort = PasswortVomSpieler

 

Da muss wieder 1 zurück kommen wenn das richtige PW eingegeben wurde.

 

Natürlich kannst du dir den ersten Schritt auch sparen(hab ich jetzt so gemacht, da du danach gefragt hast).

LG Tobi

Share this post


Link to post
Share on other sites

Ja wie gesagt, kenn mich mit SQLite nich so aus (wegen der Hochkommas)

 

Aber durch den Count bekommst du ja wieder keine Info darüber, ob jetzt nur das Passwort nicht gestimmt hat oder ob der Spieler gar nicht existiert?

 

Und muss der Fall, dass mehrere Passwörter zurückkommen überhaupt abgedeckt werden?

Ich meine wenn das der Fall is, dann wären ja mehrere Spieler mit dem identischen Login-Identifier (Username) im System, was ja eigentlich nicht sein dürfte.

Sowas muss eigentlich beim Registrierungsprozess verhindert werden

Share this post


Link to post
Share on other sites

Naja, viele Leute machen es auch so das sie nur angeben das der Benutzername oder das Passwort nicht gestimmt hat. Das bringt einerseits Sicherheit und macht es auch leichter...

Share this post


Link to post
Share on other sites

Ja passieren kann immer was....

 

Aber ich bekomme selber lieber eine zahl (0) zurück als null, damit kann ich sichergehen, das meine abfrage ok war und eben keine ergebnisse gebracht hat...

Share this post


Link to post
Share on other sites

Danke Leute für eure Vorschläge, ich denke ich werde es so wie Tiwaz vorgeschlagen hat machen

Select password from Players Where name = nameofplayer

 

Damit überprüfe ich eigentlich alles was ich brauche. :)

Share this post


Link to post
Share on other sites

Wie kommst du drauf, dass er den Zugriff lokal (vom Client) absetzt bzw. es ihm zurückgibt und dort evaluieren lässt?

 

Also da Datenbankzugriffe NIEMALS von Clients direkt durchgeführt werden sollen/dürfen, gehe ich mal sehr stark davon aus, dass das irgendwo serverseitig läuft..

Falls dem nicht so ist stelle es bitte um und verlagere Datenbankzugriffe immer auf Serverseite.

Share this post


Link to post
Share on other sites

Naja er hat ja geschrieben dass er da nicht viel Ahnung von hat.

 

Und wenn man beginnt erscheint es einem als Logisch das ganze vom Clienten an den Server zu senden und auf die Rückgabe zu reagieren.

 

Deswegen empfinde ich die Lösung mit COUNT auch als die bessere Lösung, einfach weil du keine Informationen zurückbekommst und alles über den Client laufen lassen kannst, was auch den Server bisschen entlasten sollte.

 

Könnte aber natürlich sein das ich falsch liege.

Share this post


Link to post
Share on other sites

Naja er hat ja geschrieben dass er da nicht viel Ahnung von hat.

 

Und wenn man beginnt erscheint es einem als Logisch das ganze vom Clienten an den Server zu senden und auf die Rückgabe zu reagieren.

 

Deswegen empfinde ich die Lösung mit COUNT auch als die bessere Lösung, einfach weil du keine Informationen zurückbekommst und alles über den Client laufen lassen kannst, was auch den Server bisschen entlasten sollte.

 

Könnte aber natürlich sein das ich falsch liege.

 

Das mit Count wie meinst du das, hab ich das was überlesen?

 

Edit: Achso habs gefunden aber wenn das vom Client ausgeht, ist es doch genau das selbe?

Mein Serversystem mache ich ja mit dem Unity Network, die Scripts die etwas mit der Datenbank zu tun haben sollten also eigentlich im Server sein und der Client sollte diese nicht haben oder?

Share this post


Link to post
Share on other sites

Bei

SELECT password FROM Players WHERE name = nameofplayer

bekommst du das Passwort vom Spieler zurück dessen Name ins Inputfield reingeschrieben wurde.

Danach müsstet du nochmal überprüfen ob das Passwort aus dem Inputfield gleich dem Passwort in der Datenbank ist <- Gefährlich.

 

Bei

SELECT COUNT(*) FROM Players WHERE Name = NameVomSpieler AND Passwort = PasswortVomSpieler

bekommst du nur wieviele Spieler es mit dem Namen und dem Passwort gibt, hast also keine Informationen Lokal wie das Passwort lautet.

 

Hier musst du nur drauf achten ob die Rückgabe gleich 1 ist und kannst dann weitere Informationen anfordern.

 

#Edit auf dein #Edit

 

Besser wäre es schon, würde das ganze sicherer machen, gibt aber manchmal Situationen wo man es nicht umgehen kann^^ (Wo mir aber keine auf die schnelle einfallen würde)

Share this post


Link to post
Share on other sites

Bei

SELECT password FROM Players WHERE name = nameofplayer

bekommst du das Passwort vom Spieler zurück dessen Name ins Inputfield reingeschrieben wurde.

Danach müsstet du nochmal überprüfen ob das Passwort aus dem Inputfield gleich dem Passwort in der Datenbank ist <- Gefährlich.

 

Bei

SELECT COUNT(*) FROM Players WHERE Name = NameVomSpieler AND Passwort = PasswortVomSpieler

bekommst du nur wieviele Spieler es mit dem Namen und dem Passwort gibt, hast also keine Informationen Lokal wie das Passwort lautet.

 

Hier musst du nur drauf achten ob die Rückgabe gleich 1 ist und kannst dann weitere Informationen anfordern.

 

#Edit auf dein #Edit

 

Besser wäre es schon, würde das ganze sicherer machen, gibt aber manchmal Situationen wo man es nicht umgehen kann^^ (Wo mir aber keine auf die schnelle einfallen würde)

 

Das heißt bei Methode 2, wenn 1 ausgegeben wird dann gibt es ein Spieler mit dieser Kombination und ich kann den Spieler connecten lassen?

Share this post


Link to post
Share on other sites
Das heißt bei Methode 2, wenn 1 ausgegeben wird dann gibt es ein Spieler mit dieser Kombination und ich kann den Spieler connecten lassen?

 

Bingo!

Solltest aber auch überprüfen lassen ob es möglicherweise mehrere Spieler mit dieser Kombination gibt, tritt im bestenfalls zwar nie auf aber wenn doch dann bist du wenigstens auf der sicheren Seite.

Share this post


Link to post
Share on other sites

Bingo!

Solltest aber auch überprüfen lassen ob es möglicherweise mehrere Spieler mit dieser Kombination gibt, tritt im bestenfalls zwar nie auf aber wenn doch dann bist du wenigstens auf der sicheren Seite.

Das heißt wenn größer als 1 dann sind es mehrere und dann ein Fehler ausgeben oder connecten abbrechen?

Share this post


Link to post
Share on other sites

Könnte aber natürlich sein das ich falsch liege.

Es ist grundsätzlich IMMER eine schlechte Idee wenn die Datenbank direkte Befehle vom User entgegen nehmen kann. Wer sowas zulässt hat quasi schon verloren.

Und da ist es egal, ob man dabei das Passwort zurück bekommt, die ganze Datenbank oder nur einen Count..

 

Es ist kein Kunststück sich einen Proxy runterzuladen, den Request zu intercepten und die Abfrage zu manipulieren..

Und dann steht hald da unter Umständen nicht mehr "Select Count(*)...", sondern hald vielleicht "DROP Players" und die Datenbank frisst das.

@edit:

Zusätzlich sollten Usereingaben an den Server entweder gefiltert oder - besser - auf das nötigste reduziert/abstrahiert werden.

Filtern am besten über Reguläre Ausdrücke und falls das nicht möglich ist, auf jeden Fall Sonderzeichen filtern.

Idealerweise auch mit Prepared Statements arbeiten. (dann kann man Sonderzeichen auch ruhig zulassen, was bei der Wahl der Passwörter Sinn macht)

Es ist faszinierend, wie viel Schaden man als Angreifer mit simplen SQL Injections anrichten kann und wie einfach man solche als Entwickler verhindern könnte..

 

Man sollte immer einen Server ansprechen, der dann Datenbankbefehle absetzt und die Ergebnisse auch direkt auf dem Server evaluiert und die Ergebnisse zurückgibt (hier gilt: So wenig Daten wie möglich)

Solltest aber auch überprüfen lassen ob es möglicherweise mehrere Spieler mit dieser Kombination gibt, tritt im bestenfalls zwar nie auf aber wenn doch dann bist du wenigstens auf der sicheren Seite.

Finde ich unnötig ehrlich gesagt. Sowas DARF einfach nicht passieren.. Genau so wenig wie es sein darf, dass eine Datenbank 2 Elemente mit der selben ID hat. Da wird ein Fehler geworfen und genau so sollte es auch hier gehandhabt werden.

Damit wir uns nicht falsch verstehen:

Es ist durchaus möglich einen Usernamen mehrmals zuzulassen und es spricht auch wenig dagegen, sofern sich der User dann nicht mehr mit seinem Usernamen einloggt, sondern z.B. mit seiner E-Mail. Allerdings würde ich selbst dann davon abraten den Username mehrfach vergeben zu lassen.

Also wenn ich sowas sehen würde, würden sich mir dir Zehennägel aufkräuseln.. Sowas geht imo einfach gar nicht.

Edited by Tiwaz
  • Like 1

Share this post


Link to post
Share on other sites

Es ist grundsätzlich IMMER eine schlechte Idee wenn die Datenbank direkte Befehle vom User entgegen nehmen kann. Wer sowas zulässt hat quasi schon verloren.

Und da ist es egal, ob man dabei das Passwort zurück bekommt, die ganze Datenbank oder nur einen Count..

 

Es ist kein Kunststück sich einen Proxy runterzuladen, den Request zu intercepten und die Abfrage zu manipulieren..

Und dann steht hald da unter Umständen nicht mehr "Select Count(*)...", sondern hald vielleicht "DROP Players" und die Datenbank frisst das.

Deshalb sollte man immer einen Server ansprechen der die gewünschten Selects, Updates, etc durchführt.

 

Finde ich unnötig ehrlich gesagt. Sowas DARF einfach nicht passieren.. Genau so wenig wie es sein darf, dass eine Datenbank 2 Elemente mit der selben ID hat. Da wird ein Fehler geworfen und genau so sollte es auch hier gehandhabt werden.

Damit wir uns nicht falsch verstehen:

Es ist durchaus möglich einen Usernamen mehrmals zuzulassen und es spricht auch wenig dagegen, sofern sich der User dann nicht mehr mit seinem Usernamen einloggt, sondern z.B. mit seiner E-Mail. Allerdings würde ich selbst dann davon abraten den Username mehrfach vergeben zu lassen.

Also wenn ich sowas sehen würde, würden sich mir dir Zehennägel aufkräuseln.. Sowas geht imo einfach gar nicht.

 

Ja das stimmt, mir kam dadurch noch eine andere Frage auf, ich hab dazu mal ein neues Thema geöffnet.

Share this post


Link to post
Share on other sites

Ich geb mal meinen Senf bezüglich der Sicherheit der Abfrage hinzu. ;)

 

Außerdem solltest du mit "mysql_real_escape_string()" arbeiten.

 

Auf keinen Fall, die alte mysql-API ist schon lange aus PHP entfernt worden, da sie keinen zureichenden Schutz vor SQL-Injections bietet. Bevor du diese Query irgendwo über das Web zugänglich machst, solltest du dich, falls nicht schon getan, in Prepared Statements einlesen.

 

Hier ist ein Beispiel, wie das aussehen kann.

 

Ich würde ebenfalls keine solchen hausgemachten Hashfunktionen benutzen (Rfc2898DeriveBytes basiert auf SHA1). Zu diesem Zweck gibt es genügend bewährte Algorithmen für das Hashen von Passwörtern, etwa Blowfish (Implementierung z.B. per password_hash in PHP).

  • Like 1

Share this post


Link to post
Share on other sites

Ich würde ebenfalls keine solchen hausgemachten Hashfunktionen benutzen (Rfc2898DeriveBytes basiert auf SHA1). Zu diesem Zweck gibt es genügend bewährte Bibliotheken für das Hashen von Passwörtern, etwa Blowfish (Implementierung z.B. per password_hash in PHP).

Die Methode Rfc2898DeriveBytes als "hausgemacht" zu bezeichnen, kam mir anfangs etwas gewagt vor. Schließlich ist diese im System.Security.Cryptography-Namespace von Microsoft. Dann habe ich den Link von Erdnussknacker verfolgt und wurde eines besseren belehrt. Vielen Dank für die Aufklärung.

  • Like 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...