{"id":652,"date":"2012-07-21T10:29:35","date_gmt":"2012-07-21T08:29:35","guid":{"rendered":"http:\/\/www.capri-soft.de\/blog\/?p=652"},"modified":"2012-07-21T10:29:35","modified_gmt":"2012-07-21T08:29:35","slug":"androidphp-backend-netzwerkkommunikation-authentifizierung-und-login","status":"publish","type":"post","link":"https:\/\/www.capri-soft.de\/blog\/?p=652","title":{"rendered":"Android&#038;PHP Backend: Netzwerkkommunikation, Authentifizierung und Login"},"content":{"rendered":"<h1>Aufgabenstellung<\/h1>\n<p>Es wird eine M\u00f6glichkeit gesucht eine Android App mit einen PHP Backend kommunizieren zu lassen<\/p>\n<h1>Intention<\/h1>\n<p>PHP mit MySQL Server erh\u00e4lt man oft schon mit billigem Webspace. Ein weiterer Vorteil eines fertigen Webpacks\/Webspace ist, dass es nicht notwendig wird sich um eine Backupstrategie zu k\u00fcmmern. In den meisten F\u00e4llen (SLAs und AGBs des Providers studieren) liegt dieses Problem in den H\u00e4nden des Providers. Er k\u00fcmmert sich auch um die Sicherheit des Servers. Bei Hackerattacken ist man nicht in der Verantwortung den Server zu h\u00e4rten und zu sch\u00fctzen. Daher kann der Provider auch keine Schadensersatzanspr\u00fcche gegen den Kunden geltend machen, wenn ein Server gekapert wird und z.B. mit der Installation eines Botnetzes die Leistungsf\u00e4higkeit des Rechenzentrums beeintr\u00e4chtigt ist. <\/p>\n<h1>Ansatz<\/h1>\n<ul>\n<li>Implementierung eines m\u00f6glichst einfachen Authentifierungsmechanismus in PHP mit MySQL-Anbindung<\/li>\n<li>Wegkapseln der Serviceaufrufe<\/li>\n<li>Asynchrone Verarbeitung der JSON Aufrufe per Java Thread<\/li>\n<ul>\n<li>Reaktion in der MainActivity beim Erhalten des Service-Ergebnisses f\u00fcr UI Manipulationen<\/li>\n<\/ul>\n<\/ul>\n<p>Der h\u00e4ufigste Ansatz, den man in Tutorials findet, ist die Kommunikation \u00fcber JSON, einem kompakten Datenformat in f\u00fcr Mensch und Maschine einfach lesbarer Textform zum Zweck des Datenaustauschs zwischen Anwendungen. <\/p>\n<h1>L\u00f6sung<\/h1>\n<h2>BjoernServiceCaller.java &#8211; Klasse f\u00fcr weggekapselte Service aufrufe mit CallBack-Funktionalit\u00e4t \u00fcber onLoginResult<\/h2>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\npackage com.caprisoft.contactupload.services;\r\n\r\nimport java.io.BufferedReader;\r\nimport java.io.InputStreamReader;\r\n\r\nimport org.apache.http.HttpResponse;\r\nimport org.apache.http.client.HttpClient;\r\nimport org.apache.http.client.methods.HttpPost;\r\nimport org.apache.http.entity.StringEntity;\r\nimport org.apache.http.impl.client.DefaultHttpClient;\r\nimport org.apache.http.message.BasicHeader;\r\nimport org.apache.http.params.HttpConnectionParams;\r\nimport org.apache.http.protocol.HTTP;\r\nimport org.json.JSONArray;\r\nimport org.json.JSONObject;\r\nimport org.json.JSONTokener;\r\n\r\nimport com.caprisoft.contactupload.MainActivity;\r\n\r\nimport android.content.Context;\r\nimport android.os.Looper;\r\nimport android.util.Log;\r\nimport android.widget.Toast;\r\n\r\n\r\npublic class BjoernsServiceCaller \r\n{\r\n\t\r\n\tfinal String authenticationURL = &quot;authenticationservice.php&quot;;\r\n\tprivate static BjoernsServiceCaller instance = null;\r\n\tprivate BjoernsServiceCaller() \t{}\r\n\t\r\n\r\n    \/**\r\n     * Statische Methode, liefert die einzige Instanz dieser\r\n     * Klasse zur\u00fcck\r\n     *\/\r\n    public static BjoernsServiceCaller getInstance() \r\n    {\r\n        if (instance == null) \r\n        {\r\n            instance = new BjoernsServiceCaller();\r\n        }\r\n        return instance;\r\n    }\r\n\t\r\n\t\r\n\tpublic void loginUser(final MainActivity ctx, \r\n                                    final String email, final String password) \r\n\t{\r\n        Thread t = new Thread()\r\n        {\r\n\t        public void run() \r\n\t        {\r\n                        \/\/For Preparing Message Pool for the child Thread\r\n\t\t        Looper.prepare(); \r\n\t\t\t\t\r\n\t\t        HttpClient client = new DefaultHttpClient();\r\n                         \/\/Timeout Limit\r\n\t\t        HttpConnectionParams\r\n                               .setConnectionTimeout(client.getParams(), 10000);\r\n\t\t        HttpResponse response;\r\n\t\t        JSONObject json = new JSONObject();\r\n\t\t        try\r\n\t\t        {\r\n\t\t            HttpPost post = new HttpPost(authenticationURL);\r\n\t\t            json.put(&quot;email&quot;, email);\r\n\t\t            json.put(&quot;password&quot;, password);\r\n\t\t            StringEntity se = new StringEntity( json.toString());  \r\n\t\t            se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE,\r\n                                          application\/json&quot;));\r\n\t\t            post.setEntity(se);\r\n\t\t            response = client.execute(post);\r\n\t\t            \/*Checking response *\/\r\n\t\t            if(response!=null)\r\n\t\t            {\r\n\t\t                BufferedReader reader = new BufferedReader\r\n                                (\r\n                                    new InputStreamReader\r\n                                    (\r\n                                       response.getEntity().getContent(), &quot;UTF-8&quot;\r\n                                    )\r\n                                );\r\n\t\t                String derText = reader.readLine();\r\n                                \/\/ CallBack aufruf in MainActivity\r\n\t\t                ctx.onLoginResult(derText);\r\n\t\t            }\r\n\t\t\r\n\t\t        }\r\n\t\t        catch(Exception e)\r\n\t\t        {\r\n\t\t            e.printStackTrace();\r\n\t\t        }\r\n\t\t        Looper.loop(); \/\/Loop in the message queue\r\n\t        }\r\n        };\r\n        t.start();          \r\n    }\r\n}\r\n\r\n<\/pre>\n<h2>authenticationservice.php &#8211; Das PHP Backend, was die Datenbankabfragen macht und auf jedem Billigwebspace l\u00e4uft<\/h2>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n&lt;?php  \r\n    include(&quot;configuration\/database.php&quot;);\r\n\t$json = file_get_contents(&#039;php:\/\/input&#039;);\r\n\t$obj = json_decode($json);\r\n\t$result2=mysql_query(&quot;SELECT id, activationcode FROM users &quot;.\r\n                                      &quot;WHERE email=&#039;&quot;.$obj-&gt;{&#039;email&#039;}.&quot;&#039; AND &quot;.\r\n                                      &quot;password=&#039;&quot;.$obj-&gt;{&#039;password&#039;}.&quot;&#039;&quot;) \r\n                                       or die(mysql_error());\r\n\t\r\n\t$user=&quot;nouser&quot;;\r\n\twhile ($row = mysql_fetch_array($result2, MYSQL_NUM)) {\r\n\t   $user=$row&#x5B;0];\r\n\t   $activationcode=$row&#x5B;1];\r\n\t}\t\r\n    \r\n    $posts = array(1);\r\n    \r\n    if($user!=&quot;nouser&quot;)\r\n    {\r\n    \tif($activationcode==&quot;activated&quot;)\r\n    \t{\r\n    \t\tsession_start();\r\n    \t\tsession_register(&quot;userid&quot;);\r\n    \t\t$_SESSION&#x5B;&quot;userid&quot;] =$user;\r\n    \t\theader(&#039;Content-type: application\/json&#039;);\r\n    \t\techo &quot;success&quot;;\r\n    \t}\r\n    \telse \r\n    \t{\r\n    \t   $registrationcode=substr(md5($obj-&gt;{&#039;email&#039;}.&quot; &quot;.$obj-&gt;{&#039;password&#039;}),6);\r\n    \t   mysql_query(&quot;UPDATE users SET activationcode=&#039;&quot;.$registrationcode.\r\n           &quot;&#039; WHERE email=&#039;&quot;.$obj-&gt;{&#039;email&#039;}.&quot;&#039;&quot;) or die(mysql_error());\r\n    \t   mail($obj-&gt;{&#039;email&#039;},&quot;Registrationcode for contactupload.com&quot;,\r\n            &quot;Hello!&lt;br&gt;&lt;br&gt;\\n You or someone else has registered this email &quot;.\r\n            &quot;address via mobile phone.&lt;br&gt;&lt;br&gt;\\nThe generated registrationcode is &quot;.\r\n            $registrationcode.&quot;.&lt;br&gt;&lt;br&gt;\\nPlease type this registrationcode in &quot;.\r\n            &quot;the register section of the contact sync app.&lt;br&gt;&lt;br&gt; .\r\n            &quot;\\nWith best regards,&lt;br&gt;\\ncontactupload.com&quot;);\r\n    \t\techo &quot;not activated&quot;;\r\n    \t}\r\n    }\r\n    else \r\n    {\r\n        echo &quot;not registered&quot;;\r\n    } \r\n    mysql_close($con);\r\n?&gt;\r\n<\/pre>\n<h2>MainActivity.java &#8211; Die Klasse pr\u00e4sentiert den Code der Benutzeroberfl\u00e4che der Activity (VIEW)<\/h2>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\npackage com.caprisoft.contactupload;\r\n\r\nimport com.caprisoft.contactupload.services.BjoernsServiceCaller;\r\n\r\nimport android.os.Bundle;\r\nimport android.app.Activity;\r\nimport android.util.Log;\r\nimport android.view.Menu;\r\nimport android.view.View;\r\nimport android.widget.EditText;\r\nimport android.widget.Toast;\r\n\r\npublic class MainActivity extends Activity {\r\n\t\r\n\tprivate EditText email = null;\r\n\tprivate EditText passwort = null;\r\n\t\r\n\t\/** Called when the user selects the Send button *\/\r\n\tpublic void onClickLoginButton(View view) {\r\n\t    \/\/ Do something in response to button\r\n\t\tLog.d(this.getClass().toString(), &quot;Login Button gedr\u00fcckt!&quot;);\r\n\t\tBjoernsServiceCaller.\r\n                getInstance().\r\n                loginUser\r\n                (\r\n                    this, \r\n                    email.getText().toString(), \r\n                    passwort.getText().toString()\r\n                );\r\n\t}\r\n\t\r\n\t\/** Called when the user selects the Send button *\/\r\n\tpublic void onClickRegisterButton(View view) {\r\n\t    \/\/ Do something in response to button\r\n\t\tLog.d(this.getClass().toString(), &quot;Register Button gedr\u00fcckt!&quot;);\r\n\t}\t\r\n\t\r\n\tpublic void onLoginResult(String text)\r\n\t{\r\n\t\tToast.makeText(this, &quot;HALLO: &quot;+text, Toast.LENGTH_LONG).show();\r\n\t}\r\n\r\n    @Override\r\n    public void onCreate(Bundle savedInstanceState) {\r\n        super.onCreate(savedInstanceState);\r\n        setContentView(R.layout.activity_main);\r\n        \r\n        email = (EditText) findViewById(R.id.textUsername);\r\n        passwort = (EditText) findViewById(R.id.textPassword);\r\n    }\r\n\r\n    @Override\r\n    public boolean onCreateOptionsMenu(Menu menu) {\r\n        getMenuInflater().inflate(R.menu.activity_main, menu);\r\n        return true;\r\n    }\r\n\r\n    \r\n}\r\n\r\n<\/pre>\n<h2>Activity_main.xml &#8211; Das eigentliche Frontend<\/h2>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;\r\n&lt;LinearLayout xmlns:android=&quot;http:\/\/schemas.android.com\/apk\/res\/android&quot;\r\n    xmlns:tools=&quot;http:\/\/schemas.android.com\/tools&quot;\r\n    android:orientation=&quot;vertical&quot;\r\n    android:layout_width=&quot;match_parent&quot;\r\n    android:layout_height=&quot;match_parent&quot; &gt;\r\n\r\n    &lt;TextView\r\n        android:id=&quot;@+id\/labelUsername&quot;\r\n        android:layout_width=&quot;wrap_content&quot;\r\n        android:layout_height=&quot;wrap_content&quot;\r\n        android:text=&quot;@string\/labelUsername&quot;\r\n        android:textAppearance=&quot;?android:attr\/textAppearanceLarge&quot; \/&gt;\r\n    \r\n  &lt;EditText android:id=&quot;@+id\/textUsername&quot;\r\n        android:layout_height=&quot;wrap_content&quot;\r\n        android:layout_width=&quot;match_parent&quot;\r\n        android:inputType=&quot;textNoSuggestions&quot;\r\n        android:hint=&quot;@string\/hintUsername&quot; \/&gt;\r\n  \r\n   &lt;TextView\r\n        android:id=&quot;@+id\/labelPassword&quot;\r\n        android:layout_width=&quot;wrap_content&quot;\r\n        android:layout_height=&quot;wrap_content&quot;\r\n        android:text=&quot;@string\/labelPassword&quot;\r\n        android:textAppearance=&quot;?android:attr\/textAppearanceLarge&quot; \/&gt;\r\n      \r\n   &lt;EditText android:id=&quot;@+id\/textPassword&quot;\r\n        android:layout_height=&quot;wrap_content&quot;\r\n        android:layout_width=&quot;match_parent&quot;\r\n        android:inputType=&quot;textPassword&quot;\r\n        android:hint=&quot;@string\/hintPassword&quot; \/&gt;\r\n\r\n   &lt;Button\r\n       android:id=&quot;@+id\/buttonLogin&quot;\r\n       android:layout_width=&quot;match_parent&quot;\r\n       android:layout_height=&quot;wrap_content&quot;\r\n       android:onClick=&quot;onClickLoginButton&quot;\r\n       android:text=&quot;@string\/buttonLogin&quot; \/&gt;\r\n\r\n   &lt;Button\r\n       android:id=&quot;@+id\/buttonRegister&quot;\r\n       android:layout_width=&quot;match_parent&quot;\r\n       android:layout_height=&quot;wrap_content&quot;\r\n       android:onClick=&quot;onClickRegisterButton&quot;\r\n       android:text=&quot;@string\/buttonRegister&quot; \/&gt;\r\n  \r\n&lt;\/LinearLayout&gt;\r\n\r\n<\/pre>\n<h2>AndroidManifest.xml &#8211; Permission f\u00fcr den Zugriff auf das Internet einrichten<\/h2>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n&lt;manifest xmlns:android=&quot;http:\/\/schemas.android.com\/apk\/res\/android&quot;\r\n    package=&quot;com.caprisoft.contactupload&quot;\r\n    android:versionCode=&quot;1&quot;\r\n    android:versionName=&quot;1.0&quot; &gt;\r\n\r\n    &lt;uses-sdk\r\n        android:minSdkVersion=&quot;8&quot;\r\n        android:targetSdkVersion=&quot;15&quot; \/&gt;\r\n     &lt;uses-permission android:name=&quot;android.permission.INTERNET&quot; \/&gt; \r\n    &lt;application\r\n        android:icon=&quot;@drawable\/ic_launcher&quot;\r\n        android:label=&quot;@string\/app_name&quot;\r\n        android:theme=&quot;@style\/AppTheme&quot; &gt;\r\n        &lt;activity\r\n            android:name=&quot;.MainActivity&quot;\r\n            android:label=&quot;@string\/title_activity_main&quot; &gt;\r\n            &lt;intent-filter&gt;\r\n                &lt;action android:name=&quot;android.intent.action.MAIN&quot; \/&gt;\r\n\r\n                &lt;category android:name=&quot;android.intent.category.LAUNCHER&quot; \/&gt;\r\n            &lt;\/intent-filter&gt;\r\n        &lt;\/activity&gt;\r\n    &lt;\/application&gt;\r\n&lt;\/manifest&gt;\r\n<\/pre>\n<iframe src=\"http:\/\/www.facebook.com\/plugins\/like.php?href=https%3A%2F%2Fwww.capri-soft.de%2Fblog%2F%3Fp%3D652&amp;layout=standard&amp;show_faces=true&amp;width=450&amp;action=like&amp;colorscheme=light\" scrolling=\"no\" frameborder=\"0\" allowTransparency=\"true\" style=\"border:none; overflow:hidden; width:450px;margin-top:5px;\"><\/iframe>","protected":false},"excerpt":{"rendered":"<p>Aufgabenstellung Es wird eine M\u00f6glichkeit gesucht eine Android App mit einen PHP Backend kommunizieren zu lassen Intention PHP mit MySQL Server erh\u00e4lt man oft schon mit billigem Webspace. Ein weiterer Vorteil eines fertigen Webpacks\/Webspace ist, dass es nicht notwendig wird sich um eine Backupstrategie zu k\u00fcmmern. In den meisten F\u00e4llen (SLAs und AGBs des Providers &hellip; <a href=\"https:\/\/www.capri-soft.de\/blog\/?p=652\" class=\"more-link\"><span class=\"screen-reader-text\">Android&#038;PHP Backend: Netzwerkkommunikation, Authentifizierung und Login<\/span> weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[20,15,21],"tags":[],"class_list":["post-652","post","type-post","status-publish","format-standard","hentry","category-android-sdk","category-java","category-php"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p4yGeN-aw","jetpack_likes_enabled":true,"jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=\/wp\/v2\/posts\/652","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=652"}],"version-history":[{"count":20,"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=\/wp\/v2\/posts\/652\/revisions"}],"predecessor-version":[{"id":672,"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=\/wp\/v2\/posts\/652\/revisions\/672"}],"wp:attachment":[{"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=652"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=652"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.capri-soft.de\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=652"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}