1# Tutorial - Erstellen einer Login/Register App mit MySQL/Php

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • 1# Tutorial - Erstellen einer Login/Register App mit MySQL/Php

      Guten Tag liebe Community


      Dies ist das erste einer vielzahl von Tutorial's wie man eine App für sein Forum erstellt.
      In diesen Tutorials gezeigen Code's sind abweichend von dem Orginalcode der M-Core App!



      1. Erstellen der MySQL Datenbank

      Ihr solltet euch zuerst eine MySQL Datenbank erstellen (Navicat,..). Dazu installiert ihr nun zuerst Xampp und danach Navicat (Downloadlink's sind unten zu finden). Öffnet nun die Console in Navicat in dem Ihr rechtsklickt auf eure Verbindung und auf Console klickt. Dort gebt ihr nun folgende SQL Code's ein.

      Quellcode

      1. create database android_api

      Quellcode

      1. use android_api

      Quellcode

      1. create table users(
      2. uid int(11) primary key auto_increment,
      3. unique_id varchar(23) not null unique,
      4. name varchar(50) not null,
      5. email varchar(100) not null unique,
      6. encrypted_password varchar(80) not null,
      7. salt varchar(10) not null,
      8. created_at datetime,
      9. updated_at datetime null
      Alles anzeigen


      2. Erstellen der PHP API Klassen

      Diese Funktion wird allgemein in jeder Standartverbindung der PHP API Klassen verwendet.

      Erstellt nun einen Ordner in eurem xampp/htdocs namens "android_login_api" und in diesem Ordner einen Ordner namens "include"
      Die folgenden PHP File's müssen in folgende Ordner:


      config.php - In den "include" Ordner
      DB_Connect.php - In den "include" Ordner
      DB_Functions.php - In den "include" Ordner
      index.php - In den "android_login_api" Ordner


      config.php - Einstellung zur Verbindung der Datenbank

      Quellcode

      1. define("DB_HOST", "");
      2. define("DB_USER", "");
      3. define("DB_PASSWORD", "");
      4. define("DB_DATABASE", "");
      5. ?>


      DB_Connect.php - Verbindung und schließen der Sitzung

      PHP-Quellcode

      1. <?php
      2. class DB_Connect {
      3. // constructor
      4. function __construct() {
      5. }
      6. // destructor
      7. function __destruct() {
      8. // $this->close();
      9. }
      10. // Connecting to database
      11. public function connect() {
      12. require_once 'config.php';
      13. // connecting to mysql
      14. $con = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
      15. // selecting database
      16. mysql_select_db(DB_DATABASE);
      17. // return database handler
      18. return $con;
      19. }
      20. // Closing database connection
      21. public function close() {
      22. mysql_close();
      23. }
      24. }
      25. ?>
      Alles anzeigen

      DB_Functions.php -Diese Datei enthält Funktionen, um Benutzer in der Datenbank zu speichern etc.

      PHP-Quellcode

      1. <?php
      2. class DB_Functions {
      3. private $db;
      4. //put your code here
      5. // constructor
      6. function __construct() {
      7. require_once 'DB_Connect.php';
      8. // connecting to database
      9. $this->db = new DB_Connect();
      10. $this->db->connect();
      11. }
      12. // destructor
      13. function __destruct() {
      14. }
      15. /**
      16. * Storing new user
      17. * returns user details
      18. */
      19. public function storeUser($name, $email, $password) {
      20. $uuid = uniqid('', true);
      21. $hash = $this->hashSSHA($password);
      22. $encrypted_password = $hash["encrypted"]; // encrypted password
      23. $salt = $hash["salt"]; // salt
      24. $result = mysql_query("INSERT INTO users(unique_id, name, email, encrypted_password, salt, created_at) VALUES('$uuid', '$name', '$email', '$encrypted_password', '$salt', NOW())");
      25. // check for successful store
      26. if ($result) {
      27. // get user details
      28. $uid = mysql_insert_id(); // last inserted id
      29. $result = mysql_query("SELECT * FROM users WHERE uid = $uid");
      30. // return user details
      31. return mysql_fetch_array($result);
      32. } else {
      33. return false;
      34. }
      35. }
      36. /**
      37. * Get user by email and password
      38. */
      39. public function getUserByEmailAndPassword($email, $password) {
      40. $result = mysql_query("SELECT * FROM users WHERE email = '$email'") or die(mysql_error());
      41. // check for result
      42. $no_of_rows = mysql_num_rows($result);
      43. if ($no_of_rows > 0) {
      44. $result = mysql_fetch_array($result);
      45. $salt = $result['salt'];
      46. $encrypted_password = $result['encrypted_password'];
      47. $hash = $this->checkhashSSHA($salt, $password);
      48. // check for password equality
      49. if ($encrypted_password == $hash) {
      50. // user authentication details are correct
      51. return $result;
      52. }
      53. } else {
      54. // user not found
      55. return false;
      56. }
      57. }
      58. /**
      59. * Check user is existed or not
      60. */
      61. public function isUserExisted($email) {
      62. $result = mysql_query("SELECT email from users WHERE email = '$email'");
      63. $no_of_rows = mysql_num_rows($result);
      64. if ($no_of_rows > 0) {
      65. // user existed
      66. return true;
      67. } else {
      68. // user not existed
      69. return false;
      70. }
      71. }
      72. /**
      73. * Encrypting password
      74. * @param password
      75. * returns salt and encrypted password
      76. */
      77. public function hashSSHA($password) {
      78. $salt = sha1(rand());
      79. $salt = substr($salt, 0, 10);
      80. $encrypted = base64_encode(sha1($password . $salt, true) . $salt);
      81. $hash = array("salt" => $salt, "encrypted" => $encrypted);
      82. return $hash;
      83. }
      84. /**
      85. * Decrypting password
      86. * @param salt, password
      87. * returns hash string
      88. */
      89. public function checkhashSSHA($salt, $password) {
      90. $hash = base64_encode(sha1($password . $salt, true) . $salt);
      91. return $hash;
      92. }
      93. }
      94. ?>
      Alles anzeigen


      index.php Diese Datei spielt die Rolle akzeptierte anfragen Antworten zu geben.

      PHP-Quellcode

      1. <?php
      2. /**
      3. * File to handle all API requests
      4. * Accepts GET and POST
      5. *
      6. * Each request will be identified by TAG
      7. * Response will be JSON data
      8. /**
      9. * check for POST request
      10. */
      11. if (isset($_POST['tag']) && $_POST['tag'] != '') {
      12. // get tag
      13. $tag = $_POST['tag'];
      14. // include db handler
      15. require_once 'include/DB_Functions.php';
      16. $db = new DB_Functions();
      17. // response Array
      18. $response = array("tag" => $tag, "success" => 0, "error" => 0);
      19. // check for tag type
      20. if ($tag == 'login') {
      21. // Request type is check Login
      22. $email = $_POST['email'];
      23. $password = $_POST['password'];
      24. // check for user
      25. $user = $db->getUserByEmailAndPassword($email, $password);
      26. if ($user != false) {
      27. // user found
      28. // echo json with success = 1
      29. $response["success"] = 1;
      30. $response["uid"] = $user["unique_id"];
      31. $response["user"]["name"] = $user["name"];
      32. $response["user"]["email"] = $user["email"];
      33. $response["user"]["created_at"] = $user["created_at"];
      34. $response["user"]["updated_at"] = $user["updated_at"];
      35. echo json_encode($response);
      36. } else {
      37. // user not found
      38. // echo json with error = 1
      39. $response["error"] = 1;
      40. $response["error_msg"] = "Incorrect email or password!";
      41. echo json_encode($response);
      42. }
      43. } else if ($tag == 'register') {
      44. // Request type is Register new user
      45. $name = $_POST['name'];
      46. $email = $_POST['email'];
      47. $password = $_POST['password'];
      48. // check if user is already existed
      49. if ($db->isUserExisted($email)) {
      50. // user is already existed - error response
      51. $response["error"] = 2;
      52. $response["error_msg"] = "User already existed";
      53. echo json_encode($response);
      54. } else {
      55. // store user
      56. $user = $db->storeUser($name, $email, $password);
      57. if ($user) {
      58. // user stored successfully
      59. $response["success"] = 1;
      60. $response["uid"] = $user["unique_id"];
      61. $response["user"]["name"] = $user["name"];
      62. $response["user"]["email"] = $user["email"];
      63. $response["user"]["created_at"] = $user["created_at"];
      64. $response["user"]["updated_at"] = $user["updated_at"];
      65. echo json_encode($response);
      66. } else {
      67. // user failed to store
      68. $response["error"] = 1;
      69. $response["error_msg"] = "Error occured in Registartion";
      70. echo json_encode($response);
      71. }
      72. }
      73. } else {
      74. echo "Invalid Request";
      75. }
      76. } else {
      77. echo "Access Denied";
      78. }
      79. ?>
      Alles anzeigen


      3. Das Android Projekt starten

      Zuerst sollten wir nun Eclipse starten zum Programmieren der App, den Download findet ihr unten.

      Erstellt nun ein neues Projekt indem ihr auf File -> New Android Projekt klicken. Danach füllt ihr alle Felder aus und habt nun ein neues Projekt.
      Als nächstes erstellen wie ein neues Package für unsere ganzen library files. Dazu macht ihr einen Rechtsklick auf src -> New -> Package und nennt diese "library"

      JSON Parser Klasse

      Als nächtes brauchen wir eine Parser Klasse um die JSON zu analysieren und zu antworten.
      Dazu erstellt ihr eine Neue Klasse in eurer library und nennt diese "JSONParser.java" und fügt folgenden Code unter eurem

      Quellcode

      1. package com.example....;
      .

      Java-Quellcode

      1. import java.io.BufferedReader;
      2. import java.io.IOException;
      3. import java.io.InputStream;
      4. import java.io.InputStreamReader;
      5. import java.io.UnsupportedEncodingException;
      6. import java.util.List;
      7. import org.apache.http.HttpEntity;
      8. import org.apache.http.HttpResponse;
      9. import org.apache.http.NameValuePair;
      10. import org.apache.http.client.ClientProtocolException;
      11. import org.apache.http.client.entity.UrlEncodedFormEntity;
      12. import org.apache.http.client.methods.HttpPost;
      13. import org.apache.http.impl.client.DefaultHttpClient;
      14. import org.json.JSONException;
      15. import org.json.JSONObject;
      16. import android.util.Log;
      17. public class JSONParser {
      18. static InputStream is = null;
      19. static JSONObject jObj = null;
      20. static String json = "";
      21. // constructor
      22. public JSONParser() {
      23. }
      24. public JSONObject getJSONFromUrl(String url, List<NameValuePair> params) {
      25. // Making HTTP request
      26. try {
      27. // defaultHttpClient
      28. DefaultHttpClient httpClient = new DefaultHttpClient();
      29. HttpPost httpPost = new HttpPost(url);
      30. httpPost.setEntity(new UrlEncodedFormEntity(params));
      31. HttpResponse httpResponse = httpClient.execute(httpPost);
      32. HttpEntity httpEntity = httpResponse.getEntity();
      33. is = httpEntity.getContent();
      34. } catch (UnsupportedEncodingException e) {
      35. e.printStackTrace();
      36. } catch (ClientProtocolException e) {
      37. e.printStackTrace();
      38. } catch (IOException e) {
      39. e.printStackTrace();
      40. }
      41. try {
      42. BufferedReader reader = new BufferedReader(new InputStreamReader(
      43. is, "iso-8859-1"), 8);
      44. StringBuilder sb = new StringBuilder();
      45. String line = null;
      46. while ((line = reader.readLine()) != null) {
      47. sb.append(line + "n");
      48. }
      49. is.close();
      50. json = sb.toString();
      51. Log.e("JSON", json);
      52. } catch (Exception e) {
      53. Log.e("Buffer Error", "Error converting result " + e.toString());
      54. }
      55. // try parse the string to a JSON object
      56. try {
      57. jObj = new JSONObject(json);
      58. } catch (JSONException e) {
      59. Log.e("JSON Parser", "Error parsing data " + e.toString());
      60. }
      61. // return JSON String
      62. return jObj;
      63. }
      64. }
      Alles anzeigen


      SQL Database Handler Klasse

      Ich benutze in der Anwendung eine SQLite Datenbank zum speicher von Benutzerdaten. Doch es bleibt euch überlasse welche Ihr wählt.

      Erstellt nun wieder ein neues package namens "DatabaseHandler.java" und füge folgenden Code hinzu nach

      Quellcode

      1. package com.example....;
      .

      Java-Quellcode

      1. import java.util.HashMap;
      2. import android.content.ContentValues;
      3. import android.content.Context;
      4. import android.database.Cursor;
      5. import android.database.sqlite.SQLiteDatabase;
      6. import android.database.sqlite.SQLiteOpenHelper;
      7. public class DatabaseHandler extends SQLiteOpenHelper {
      8. // All Static variables
      9. // Database Version
      10. private static final int DATABASE_VERSION = 1;
      11. // Database Name
      12. private static final String DATABASE_NAME = "android_api";
      13. // Login table name
      14. private static final String TABLE_LOGIN = "login";
      15. // Login Table Columns names
      16. private static final String KEY_ID = "id";
      17. private static final String KEY_NAME = "name";
      18. private static final String KEY_EMAIL = "email";
      19. private static final String KEY_UID = "uid";
      20. private static final String KEY_CREATED_AT = "created_at";
      21. public DatabaseHandler(Context context) {
      22. super(context, DATABASE_NAME, null, DATABASE_VERSION);
      23. }
      24. // Creating Tables
      25. @Override
      26. public void onCreate(SQLiteDatabase db) {
      27. String CREATE_LOGIN_TABLE = "CREATE TABLE " + TABLE_LOGIN + "("
      28. + KEY_ID + " INTEGER PRIMARY KEY,"
      29. + KEY_NAME + " TEXT,"
      30. + KEY_EMAIL + " TEXT UNIQUE,"
      31. + KEY_UID + " TEXT,"
      32. + KEY_CREATED_AT + " TEXT" + ")";
      33. db.execSQL(CREATE_LOGIN_TABLE);
      34. }
      35. // Upgrading database
      36. @Override
      37. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
      38. // Drop older table if existed
      39. db.execSQL("DROP TABLE IF EXISTS " + TABLE_LOGIN);
      40. // Create tables again
      41. onCreate(db);
      42. }
      43. /**
      44. * Storing user details in database
      45. * */
      46. public void addUser(String name, String email, String uid, String created_at) {
      47. SQLiteDatabase db = this.getWritableDatabase();
      48. ContentValues values = new ContentValues();
      49. values.put(KEY_NAME, name); // Name
      50. values.put(KEY_EMAIL, email); // Email
      51. values.put(KEY_UID, uid); // Email
      52. values.put(KEY_CREATED_AT, created_at); // Created At
      53. // Inserting Row
      54. db.insert(TABLE_LOGIN, null, values);
      55. db.close(); // Closing database connection
      56. }
      57. /**
      58. * Getting user data from database
      59. * */
      60. public HashMap<String, String> getUserDetails(){
      61. HashMap<String,String> user = new HashMap<String,String>();
      62. String selectQuery = "SELECT * FROM " + TABLE_LOGIN;
      63. SQLiteDatabase db = this.getReadableDatabase();
      64. Cursor cursor = db.rawQuery(selectQuery, null);
      65. // Move to first row
      66. cursor.moveToFirst();
      67. if(cursor.getCount() > 0){
      68. user.put("name", cursor.getString(1));
      69. user.put("email", cursor.getString(2));
      70. user.put("uid", cursor.getString(3));
      71. user.put("created_at", cursor.getString(4));
      72. }
      73. cursor.close();
      74. db.close();
      75. // return user
      76. return user;
      77. }
      78. /**
      79. * Getting user login status
      80. * return true if rows are there in table
      81. * */
      82. public int getRowCount() {
      83. String countQuery = "SELECT * FROM " + TABLE_LOGIN;
      84. SQLiteDatabase db = this.getReadableDatabase();
      85. Cursor cursor = db.rawQuery(countQuery, null);
      86. int rowCount = cursor.getCount();
      87. db.close();
      88. cursor.close();
      89. // return row count
      90. return rowCount;
      91. }
      92. /**
      93. * Re crate database
      94. * Delete all tables and create them again
      95. * */
      96. public void resetTables(){
      97. SQLiteDatabase db = this.getWritableDatabase();
      98. // Delete All Rows
      99. db.delete(TABLE_LOGIN, null, null);
      100. db.close();
      101. }
      102. }
      Alles anzeigen


      User Function Klasse

      Erstellt nun wieder eine neue Klasse unter dem library package und nennt diese "UserFunctions.java"
      fügt wieder folgenden Code hinzu nach:

      Quellcode

      1. package com.example....;
      .

      Java-Quellcode

      1. import java.util.ArrayList;
      2. import java.util.List;
      3. import org.apache.http.NameValuePair;
      4. import org.apache.http.message.BasicNameValuePair;
      5. import org.json.JSONObject;
      6. import android.content.Context;
      7. public class UserFunctions {
      8. private JSONParser jsonParser;
      9. // Testing in localhost using wamp or xampp
      10. // use [URL]http://10.0.2.2/[/URL] to connect to your localhost ie [URL="http://localhost/"]BlackEvolution - Coming Soon[/URL]
      11. private static String loginURL = "[URL]http://10.0.2.2/ah_login_api/[/URL]";
      12. private static String registerURL = "[URL]http://10.0.2.2/ah_login_api/[/URL]";
      13. private static String login_tag = "login";
      14. private static String register_tag = "register";
      15. // constructor
      16. public UserFunctions(){
      17. jsonParser = new JSONParser();
      18. }
      19. /**
      20. * function make Login Request
      21. * @param email
      22. * @param password
      23. * */
      24. public JSONObject loginUser(String email, String password){
      25. // Building Parameters
      26. List<NameValuePair> params = new ArrayList<NameValuePair>();
      27. params.add(new BasicNameValuePair("tag", login_tag));
      28. params.add(new BasicNameValuePair("email", email));
      29. params.add(new BasicNameValuePair("password", password));
      30. JSONObject json = jsonParser.getJSONFromUrl(loginURL, params);
      31. // return json
      32. // Log.e("JSON", json.toString());
      33. return json;
      34. }
      35. /**
      36. * function make Login Request
      37. * @param name
      38. * @param email
      39. * @param password
      40. * */
      41. public JSONObject registerUser(String name, String email, String password){
      42. // Building Parameters
      43. List<NameValuePair> params = new ArrayList<NameValuePair>();
      44. params.add(new BasicNameValuePair("tag", register_tag));
      45. params.add(new BasicNameValuePair("name", name));
      46. params.add(new BasicNameValuePair("email", email));
      47. params.add(new BasicNameValuePair("password", password));
      48. // getting JSON Object
      49. JSONObject json = jsonParser.getJSONFromUrl(registerURL, params);
      50. // return json
      51. return json;
      52. }
      53. /**
      54. * Function get Login status
      55. * */
      56. public boolean isUserLoggedIn(Context context){
      57. DatabaseHandler db = new DatabaseHandler(context);
      58. int count = db.getRowCount();
      59. if(count > 0){
      60. // user logged in
      61. return true;
      62. }
      63. return false;
      64. }
      65. /**
      66. * Function to logout user
      67. * Reset Database
      68. * */
      69. public boolean logoutUser(Context context){
      70. DatabaseHandler db = new DatabaseHandler(context);
      71. db.resetTables();
      72. return true;
      73. }
      74. }
      Alles anzeigen


      Teil 2 wird nächste Woche kommen und dort werde ich euch zeigen, wie man das Design der Android App mit den Funktionen verbindet.
      Bis dahin


      Euer Armin ♥

      [HR][/HR]
      Downloadlinks

      Xampp
      Navicat
      Eclipse

      Alle Downloadlinks sind von Chip.de und enthalten keinerlei Vieren etc.


      [HR][/HR]
      Credits


      Ein besonderes Dankeschön geht an meine Kollegen von Androhive.info die mit mir daran gearbeiten haben und mir die möglichkeit geben haben solch tolle funktionen gemeinsam mit Ihnen zu erstellen. Natürlich möchte ich mein Team "LAZY" nicht vergessen die mir die bekanntschaft gemacht haben.[HR][/HR]
    • Werbung zur Unterstützung des Forums ( Bitte AddBlocker deaktivieren )

      • Die mysql Erweiterung sollte in neueren Projekten nicht mehr verwendet werden ... In der PHP Dokumentation wird zu mysqli oder PDO geraten.
      • In DB_Connect config.php einzubinden und mit diesen globalen Variablen die Datenbankverbindung herzustellen ist extrem unflexibel. Deine Klasse ist nicht nur an eine andere Datei gebunden, sie kann auch nur zu einer einzigen Datenbank verbinden, ist also alles andere als wiederverwendbar. Schlechter Stil.
      • Auch wenn du die Verbindung in einer Klasse herstellst, ist dein Code so nicht objektorientiert. Würdest du die Methode von DB_Connect static machen (das würde bei der mangelnden Flexibilität keinen Unterschied machen), könntest du auch einfach Funktionen nehmen.
      • Teilweise schreibst du das public vor die Methoden, teilweise nicht (schlechter Stil). Zudem hast du leere Konstruktore und Desktuktore. Die brauchst du nicht ...
      • DB_Functions ist ebenso unflexibel. Wieso übergibst du das DB_Connect-Objekt nicht dem Konstruktor oder einem Setter? Dann könntest du wenigstens die Datenbankverbindung austauschen (wenn DB_Connect zu verschiedenen Datenbanken verbinden könnten). Mag sein, dass ich das übertrieben kritisere, aber ich mag einfach keinen prozeduralen Quelltext, der in Klassen gepresst wurde. OOP steigert die Codequalität nicht immer ...
      • Du wechselst ständig zwischen Anführungszeichen und Hochkommas für Strings. Schlechter Stil ...
      • Ganz wichtig: Dein Code ist nicht gegen SQL Injections gesichert!
      • Der Stacktrace sollte im Release nicht mehr ausgegeben werden ... (JSON"Parser")
      • DatabaseHandler: Du bezeichnest die Klasse als Paket. Du kennst aber den Unterschied?!
      • Zum Android-Code kann ich nichts sagen, ich programmiere keine Apps ...
      • Wieso bezeichnest du das hier als Tutorial? Du erklärst nur, welcher Quelltext in welche angelegte Datei kopiert werden soll. Ähm ja, wenn man das dann mal auswendig kann ist man ja schon fast ein Guru ...
    • Gebe ich dir in manchen Punkten recht, doch die meisten kennen sich nicht sogut aus wie du und ich, und wissen nicht was eine SQL Injection etc ist. Dies hier dient nur zu lernzwecken und soll keine App für Microsoft werden. Mann kann ja Anfänger nicht direkt mit jedem einzelen Punkt konfrontieren, und ich bin auch nicht in der Lage wie die richtigen Spezialisten alles genaustens zu erklären. Denn auch ich bin kein Profi und muss ab und zu mal nachschlagen in Büchern bzw google.

      Außerdem geht es ja nicht um die PHP Funktion, sondern um die App allgemein, denn dort wird alles durch die sogenannten Injection's mehr oder weniger geschützt. Da man ja schlecht mit einem Android Gerät sich in eine Datenbank hacken kann..
    • Na ja, die Sicherheitslücke besteht im PHP Skript, und das kann auch vom PC aufgerufen werden.

      Es mag richtig sein, dass es für einen Anfänger kaum relevant ist, wie sicher sein Skript ist. Aber sobald er dann an etwas arbeitet, das er veröffentlichen oder online stellen möchte, ist das ein sehr wichtiges Thema. Bei deinem Quelltext kann ein Angreifer so gut wie alles mit deiner Datenbank anstellen. Er kann sich mit jedem beliebigen Account anmelden, sich alle Benutzerdaten anschauen, sie löschen, ... Das ist eine wirklich fatale Sicherheitslücke. Um die Kritik etwas konstruktiver zu machen: Du kannst die Sicherheitslücke schließen, indem du prepared statements von mysqli nutzt oder indem du jede Variable, die du in einem Query verwendest und die Eingaben des Benutzers erhält, mit mysql_real_escape_string() sicherst.

      Gebe ich dir in manchen Punkten recht, doch die meisten kennen sich nicht sogut aus wie du und ich, und wissen nicht was eine SQL Injection etc ist.

      Dann solltest du aber einen Hinweis darauf geben, dass der Quelltext auf keinen Fall so verwendet werden sollte.