# Passwort aus DB auslesen



## Antoras (5. Mai 2009)

Hallo,

ich würde gerne für einen Loginmanager einen Benutzernamen und das dazugehörige Passwort aus einer Datenbank auslesen. Der Benutzername funktioniert auch, nur das Passwort nicht und ich versteh nicht warum. Die Kommandos zum Auslesen:

```
char[] correctPassword = null;
String pass = String.valueOf(password);
String checkPassword = "SELECT password FROM" + USER +
	"WHERE password='" + pass + "'";
Statement s = connection.createStatement();
ResultSet r = s.executeQuery(checkPassword);
			
while (r.next()) {
	System.out.print(r.getString(1) + " || ");
	System.out.println(r.getString(2));
	correctPassword = r.getString(2).toCharArray();
}
```
Der erste Wert wird ohne Probleme ausgelesen, nur beim zweiten bekomm ich die Fehlermeldung, dass der Wert nicht existiert. Das tut er aber definitiv.
Kurioserweise kann ich mit diesem String 

```
String show = "SELECT * FROM" + USER;
```
alle Daten auch auslesen.
Was stimmt mit dem String _checkPassword_ nicht?

Was anderes: Momentan lese ich das Passwort aus einem JPasswordField als char-Array aus. Das richtige Passwort wird als String aus der Datenbank ausgelesen, dann in ein char-Array umgewandelt und dann auf Gleichheit überprüft. Ist das sinnvoll?  Oder gibt es da bessere Vorgehensweisen?


----------



## Schandro (5. Mai 2009)

```
String checkPassword = "SELECT password FROM" + USER +
    "WHERE password='" + pass + "'";
```
Entweder hab ich grad en Denkfehler, oder dieses Query ist Schwachsinn. 

Das Query ist so als würdest du fragen: "Hey Tim Mälzer, wie heißt du?"


----------



## sparrow (5. Mai 2009)

Was der Schandro dir damit sagen will:

du suchst in der Tabelle "User" nach dem Passwort. Bringst es aber überhaupt nicht mit dem Benutzernamen in Verbindung.

In diesem Codestück greifst du auf 2 Spalten der Abfrage zu:

```
System.out.print(r.getString(1) + " || ");
    System.out.println(r.getString(2));
```

Mit dieser Abfrage fragst du aber nur 1 Spalte ab:
	
	
	
	





```
String checkPassword = "SELECT password FROM" + USER +
    "WHERE password='" + pass + "'";
```

Die Fehlermeldung hat recht, da gibbet keine 2. Spalte.


Übrigens: Ich persönlich finde es 'angenehmer' einfach zählen zu lassen auf wie viele Tupel Name und Passwort zutreffen. >0 ist dann eine entsprechend gültige Kombination.


Gruß
Sparrow


----------



## SlaterB (5. Mai 2009)

> "SELECT password FROM" + USER + "WHERE password=...

ganz allgemein unabhängig von der Anwendung: 
wenn hier nicht USER links + rechts Leerzeichen enthält, explodiert ein Atomkraftwerk,
viel einfacher und sicherer ist

"SELECT password FROM " + USER + " WHERE password=...

für ALLE Queries merken, auch bei der nächsten, SELECT * FROM...


----------



## ARadauer (5. Mai 2009)

> explodiert ein Atomkraftwerk,


 ah darum der hinweis in der jdk lizenz...

generell:
1. query mal auf die konsole ausgeben lassen
2. das quer mit phpmyadmin oder sonst einem sql tool ausführen... was kommt da?
3. was hat die passwort spalte für einen datentyp?


----------



## Antoras (5. Mai 2009)

> Das Query ist so als würdest du fragen: "Hey Tim Mälzer, wie heißt du?"


Hab das jetzt zu _SELECT * FROM_ geändert. Macht anders echt keinen Sinn.



> Ich persönlich finde es 'angenehmer' einfach zählen zu lassen auf wie viele Tupel Name und Passwort zutreffen. >0 ist dann eine entsprechend gültige Kombination.


Stimmt, macht mehr Sinn. Die nachfolgende Überprüfung ob die Passwörter übereinstimmen bringt nichts. Aber wie frag ich am besten ab, ob die Logindaten >0? Mit einer Funktion direkt in SQL?



> wenn hier nicht USER links + rechts Leerzeichen enthält, explodiert ein Atomkraftwerk,


Diesem Fehler bin ich glücklicherweise schon begegnet. Hab ihn mit dem Debugger bemerkt. Hab das aber eher so gelöst, dass ich vor und nach dem String _USER_ direkt ein Leerzeichen angehängt hab. So muss ich nicht jedes Mal nachgucken ob ich die Leerzeichen jetzt in den String eingebaut hab. 



> was hat die passwort spalte für einen datentyp?


String (varchar)

Hab meine Methode zum Einloggen jetzt soweit geändert:

```
public boolean isLoginCorrect(String userName, char[] passWord) {
	boolean isCorrect = false;
	String pass = String.valueOf(passWord);
	String login = "SELECT * FROM" + USER +
			"WHERE username='" + userName + "'" +
			"AND password='" + pass + "'";
	
	try {
		Statement s = connection.createStatement();
		ResultSet r = s.executeQuery(login);
		
		while (r.next()) {
			if (s.execute(login)) {
				isCorrect = true;
			}
		}
		
		s.close();
	} catch (SQLException e) {
		ExceptionHandler.logCriticalException(e.getLocalizedMessage());
	}
	
	return isCorrect;
}
```
Das Einloggen geht jetzt. Das Problem ist nur, dass ich jetzt zwei mal eine Anfrage an die DB starten muss. Ist natürlich Blödsinn. Aber mir fällt gerade irgendwie keine bessere Lösung ein. Hat jemand einen Vorschlag?


----------



## sparrow (5. Mai 2009)

1. Bau die Leerzeichen in die Query und nicht an einen Teilstring. Du siehst, dass bringt andere Leute die deinen Code lesen nur durcheinander.
2. Schau bei Gelegenheit PreparedStatements, das ist in diesem Fall aber unnötig und an dieser Stelle nur als Lernhinweis gedacht.
3. Der SQL-Befehl count gibt dir die Anzahl der Zeilen einer Abfrage zurück. SQL COUNT

Es ist auch in deinem aktuellen Code nur eine Abfrage nötig, die Abfrage während du das ResultSet durchläufst ist unnötig.


----------



## Antoras (6. Mai 2009)

sparrow hat gesagt.:


> 1. Bau die Leerzeichen in die Query und nicht an einen Teilstring. Du siehst, dass bringt andere Leute die deinen Code lesen nur durcheinander.
> Ok. hab es geändert.
> 
> 2. Schau bei Gelegenheit PreparedStatements, das ist in diesem Fall aber unnötig und an dieser Stelle nur als Lernhinweis gedacht.
> ...


..


----------



## sparrow (6. Mai 2009)

Antoras hat gesagt.:


> Kann man das mit COUNT auch nur mit einem Kommando realisieren?



Das ist doch nur 1 Kommando?


```
SELECT COUNT(*) FROM user WHERE username='test' AND password='test'
```

Machst doch alles richtig. Ein Kommando das prüft ob es einen Eintrag mit dem Namen und dem Passwort gibt.


----------



## Antoras (6. Mai 2009)

Hm, das Kommando geht ja wirklich. Heute Nacht ging es nicht. ka was ich da gedacht bzw. falsch gemacht hab ???:L

Aber jetzt geht ja alles. 

Danke für eure Antworten. Wart mir eine große Hilfe. :applaus:


----------



## xote (7. Mai 2009)

Ist es eigentlich richtig, wenn man passwörter in die DB schreibt? Im Normalfall nehme ich immer Abstand davon, aber vielleicht gibt es ja gute Gründe dafür.


----------



## tfa (7. Mai 2009)

Normalerweise sollte man nur Hashs von Passwörtern in DBs schreiben.


----------



## ARadauer (8. Mai 2009)

> aber vielleicht gibt es ja gute Gründe dafür.


tja die klartext passwörter seiner kunden in verbindung mit mail adressen können schon interessant sein ;-)


----------

