วันพฤหัสบดีที่ 6 ตุลาคม พ.ศ. 2559

Http Post using Loopj to Laravel 5.3

ความเดิมตอนที่แล้ว เรื่อง การ Get HTTP โดยใช้ Loopj  วันนี้ เราลองมา post ข้อมูลจาก Android ลงใน HTTP ดูบ้าง

เริ่มต้นเตรียม Post method ไว้ก่อน กรณีไม่ใช้ Laravel 5.3

ตั้งชื่อ script เช่น mypost.php (ใน web server directory)
<?php
    echo "id: ".$_POST["id"]." message:".$_POST["message"];



ใน Android ได้ปรับปรุง Code ดังนี้
ใน MainActivity.java จากคราวที่แล้วจะเพิ่ม method เพียงเท่านี้ ก็สามารถที่จะ post ลงใน PHP script ที่รอรับ Action ได้แล้ว โดยการเพิ่ม params object เข้าไป ซึ่งจะเป็น parameter ของ

static void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
    client.post(getAbsoluteUrl(url), params, responseHandler);
}

ใน ClientFacade.java โดย RequestParam ก็คือค่าของ html element หรือ parameter ที่เรา Post ไปนั่นเอง

แต่ถ้าเราใช้ code เดียวกันนี้ Post ไปใน Laravel 5.3 โดยกำหนด Route ดังนี้

Route::post('/android/testPost', function (Request $request) {
        echo $request->input('id');
        echo $request->input('message');

        $mesg = new App\Message;
        $mesg->user_id = 1;
        $mesg->message = $request->input('message');
        $mesg->save();
});

เราจะได้ค่า HTTP status 500 กลับมา โดย onFailure() จะถูกเรียก นั่นเป็นเพราะว่า Verify CSRF ไม่ผ่าน เพราะ Code PHP ข้างบนไม่ได้มีการ Verify CSRF

เราต้องส่ง request get เพื่อไปร้องขอ _token โดยอ่านจาก Cookie XSRF-TOKEN จาก server ก่อน แล้วนำค่านั้นไปใส่ใน _token
params.put("_token","AZzS6jPpsdlWv9nNTByaE3OIj4I1FQg8hrhHXkH8");

แต่ก็คงไม่สะดวกเท่าไร ถ้าต้องมา get _token บ่อย ๆ ผมใช้วิธีแบบง่ายที่สุดคือ disable CSRF ทำได้โดยการ comment ที่ app\Http\Kernel.php ในตัวแปร $middlewareGroups ไป comment ค่า ตัวแปร array web ที่เราไม่ต้องการได้เลย  แต่ถ้า comment ตรงนี้ ทุก ๆ Route ก็จะไม่ถูก verify CSRF วิธีที่ดีกว่า คือไป เพิ่ม การยกเว้นที่ไม่ต้องตรวจสอบ CSRF ที่ app\Http\Middleware\VerifyCsrfToken.php

class VerifyCsrfToken extends BaseVerifier{
    protected $except = [
        'android/*'        
   ];
}

หมายความว่า URI (ไม่นับ hostname จนถึง Root directory (/public) ) ที่ตรงกับค่าในตัวแปร $except จะไม่ถูกตรวจสอบ CSRF พอทดลอง run อีกครั้งคราวนี้ มี record เพิ่มขึ้นในตารางแล้ว

อย่างไรก็ดี การปิด CSRF ก็ไม่ใช่วิธีที่ถูกต้อง แม้ว่าจะ Post มาจาก Android Application ก็ตาม เพราะ เป็นช่องโหว่ ให้ Laravel ก็มีโอกาสโดน CSRF ได้

วิธีที่ดีกว่าคือใช้ API Guard : https://github.com/chrisbjr/api-guard ไว้ ทดลองแล้วจะมาเล่าให้ฟังใหม่นะครับ

SourceCode:  https://github.com/wwarodom/HttpExample


Reference: 
http://loopj.com/android-async-http/
http://yasirameen.com/2016/05/asynchronous-http-client-android/
http://stackoverflow.com/questions/13052036/posting-json-xml-using-android-async-http-loopj

ไม่มีความคิดเห็น: