2017-02-24 19 views
14

Tôi là người mới chơi phát triển Android. Tôi đang sử dụng android studio để phát triển một ứng dụng. Những điều tôi đã thực hiệnBảo mật api php để sử dụng trong ứng dụng android

  1. Tạo một DB với hai bảng trong đó trong MySQL.
  2. Đã tạo hai riêng biệt api's cho cả hai phương thức GETPOST.
  3. truy cập thành công cả api's

gì tôi đã đạt được cho bây giờ

  1. Có thể GET dữ liệu hình thành nên GET api.
  2. Có thể POST dữ liệu bằng cách sử dụng POST api

gì tôi phải làm gì bây giờ

Tôi muốn api của tôi để xuất bản trực tuyến, ví dụ: tôi muốn triển khai dịch vụ của tôi vào một máy chủ và truy cập chúng. Tại thời điểm này tôi có thể triển khai các dịch vụ trên máy chủ và truy cập chúng.

Bây giờ tôi muốn dịch vụ của tôi (api's) được bảo mật. Đối với điều đó tôi đã tìm kiếm nhiều bài báo và tìm thấy hai cách.

  1. Sử dụng khung yii. Có người nói với tôi để sử dụng nó bởi vì nó tự động bảo đảm api's. Nhưng tôi không biết chắc nó có làm hay không.
  2. thủ bảo đảm api's

Đối với điểm 1 khuôn khổ sẽ rất hữu ích nhưng nó là mới với tôi và nó sẽ mất thời gian để coop với nó như tôi đang đã tạo ra các dịch vụ web.

Đối với điểm 2 tôi đã nhận một số thông tin

  1. using HMAC_SHA1
  2. DETECTING MOBILE DEVICES USING PHP

Cả hai liên kết có vẻ là tốt, nhưng liên kết 1 không mang lại cho tôi nhiều thông tin về điều đó.

Rõ ràng tôi muốn đảm bảo cả hai api's

Bây giờ mã phần

GET_DATA.php

require_once ('config.php'); 

$sql = "SELECT * FROM users"; 


$r = mysqli_query($con,$sql); 

$result = array(); 

while($row = mysqli_fetch_array($r)){ 
array_push($result,array(
    'Id'=>$row['Id'], 
    'Name'=>$row['Name'] 
));} 

vang json_encode (mảng (kết quả => $ 'người sử dụng' của tôi));

POST_DATA.php

require_once ('config.php'); 

$return_arr = array(); 

$UserId=($_POST['UserId']); 
$Latitude=($_POST['Latitude']); 
$Longitude=($_POST['Longitude']); 
$DateTime=($_POST['DateTime']); 


$user_register_sql1 = "INSERT INTO `activity`(`Id`,`UserId`, `Latitude`,`Longitude`,`DateTime`) values (NULL,'".$UserId."','".$Latitude."','".$Longitude."','".$DateTime."')"; 
mysqli_query ($con,$user_register_sql1); 
$row_array['errorcode1'] = 1; 

Tôi có một user class từ mà tôi đang nhận được usernameID

JSONfunctions.java

lớp này có nhiệm vụ nhận dữ liệu từ api

public static JSONObject getJSONfromURL(String url) 
{ 

    String json = ""; 
    JSONObject jsonObject = null; 
    try 
    { 
     HttpClient httpClientt = new DefaultHttpClient(); 
     HttpGet httpGet = new HttpGet(url); 
     HttpResponse httpResponse = httpClientt.execute(httpGet); 
     BufferedReader br = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent())); 
     StringBuffer sb = new StringBuffer(); 
     String line = ""; 
     while ((line = br.readLine()) != null) { 
      sb.append(line); 
     } 

     json = sb.toString(); 
    } catch (ClientProtocolException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    try 
    { 
     jsonObject = new JSONObject(json); 
    } catch (JSONException e) { 
     e.printStackTrace(); 
    } 

    return jsonObject; 
} 

PutUtility.Java

lớp này có nhiệm vụ POST phương pháp

public void setParam(String key, String value) { 
    params.put(key, value); 
} 

public String postData(String Url) { 

    StringBuilder sb = new StringBuilder(); 
    for (String key : params.keySet()) { 
     String value = null; 
     value = params.get(key); 


     if (sb.length() > 0) { 
      sb.append("&"); 
     } 
     sb.append(key + "=" + value); 
    } 

    try { 
     // Defined URL where to send data 

     URL url = new URL(Url); 

     URLConnection conn = null; 
     conn = url.openConnection(); 

     // Send POST data request 
     httpConnection = (HttpURLConnection) conn; 
     httpConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 
     httpConnection.setRequestMethod("POST"); 
     httpConnection.setDoInput(true); 
     httpConnection.setDoOutput(true); 
     OutputStreamWriter wr = null; 

     wr = new OutputStreamWriter(conn.getOutputStream()); 
     wr.write(sb.toString()); 
     wr.flush(); 

     BufferedReader in = new BufferedReader(
       new InputStreamReader(httpConnection.getInputStream())); 
     String inputLine; 
     response = new StringBuffer(); 

     while ((inputLine = in.readLine()) != null) { 
      response.append(inputLine); 
     } 
     in.close(); 

    } catch (MalformedURLException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    }finally { 
     try { 
      reader.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 


    return response.toString(); 
} 

MainActivity.java

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    _latitude = (TextView)findViewById(R.id.latitude); 
    _longitude = (TextView)findViewById(R.id.longitude); 
    btn_get_coordinates = (Button)findViewById(R.id.button); 
    btn_save_data = (Button)findViewById(R.id.btn_save); 


    btn_save_data.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 

      if(UserId.toString()== "" || Latitude.toString() == "" || Longitude.toString() == "" || DateTime.toString() == "") 
      { 
       Toast.makeText(getApplicationContext(), "Data Not Saved !!!! Please select appropriate data to save", Toast.LENGTH_SHORT).show(); 
      } 


      new ServiceLogin().execute(UserId, Latitude, Longitude, DateTime); 

     } 
    }); 

    // Download JSON file AsyncTask 
    new DownloadJSON().execute(); 
} 
    // Download JSON file AsyncTask 
private class DownloadJSON extends AsyncTask<Void, Void, Void> 
{ 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     progressDialog = new ProgressDialog(MainActivity.this); 
     progressDialog.setMessage("Fetching Users....!"); 
     progressDialog.setCancelable(false); 
     progressDialog.show(); 

    } 

    @Override 
    protected Void doInBackground(Void... params) { 

     // Locate the Users Class 
     users = new ArrayList<Users>(); 

     // Create an array to populate the spinner 
     userList = new ArrayList<String>(); 
     // http://10.0.2.2:8000/MobileApp/index.php 
     //http://10.0.2.2:8000/app/web/users/ 
     //http://192.168.100.8:8000/app/web/users/ 
     // JSON file URL address 
     jsonObject = JSONfunctions.getJSONfromURL("http://192.168.100.9:8000/MobileApp/GET_DATA.php"); 

     try 
     { 
      JSONObject jobj = new JSONObject(jsonObject.toString()); 
      // Locate the NodeList name 
      jsonArray = jobj.getJSONArray("users"); 

      for(int i=0; i<jsonArray.length(); i++) 
      { 
       jsonObject = jsonArray.getJSONObject(i); 

       Users user = new Users(); 

       user.setId(jsonObject.optString("Id")); 
       user.setName(jsonObject.optString("Name")); 
       users.add(user); 

       userList.add(jsonObject.optString("Name")); 

      } 
     } catch (JSONException e) { 
      Log.e("Error", e.getMessage()); 
      e.printStackTrace(); 
     } 


     return null; 
    } 

    @Override 
    protected void onPostExecute(Void args) 
    { 
     // Locate the spinner in activity_main.xml 
     Spinner spinner = (Spinner)findViewById(R.id.spinner); 

     // Spinner adapter 
     spinner.setAdapter(new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_spinner_dropdown_item, userList)); 

     // Spinner on item click listener 

     spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 


      @Override 
      public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 

       textViewResult = (TextView)findViewById(R.id.textView); 

       // Set the text followed by the position 

       textViewResult.setText("Hi " + users.get(position).getName() + " your ID is " + users.get(position).getId()); 
       UserId = String.valueOf(users.get(position).getId()); 
       progressDialog.dismiss(); 
       _latitude.setText(""); 
       _longitude.setText(""); 
       Latitude = null; 
       Longitude= null; 

      } 

      @Override 
      public void onNothingSelected(AdapterView<?> parent) { 
       textViewResult.setText(""); 
      } 
     }); 
    } 


} 

Như i am newbie, vì vậy tôi không biết phải làm gì trong php tập lệnh và phải làm gì trong mã android của tôi :(. Nó sẽ rất hữu ích nếu bất cứ ai có thể hướng dẫn tôi hoặc cho tôi một hướng dẫn mà tôi làm theo.

Mọi trợ giúp sẽ được đánh giá cao.

Trả lời

7

Để bảo mật các API của bạn, bạn cần một cơ chế để phát hiện rằng yêu cầu api được tạo từ một nguồn đáng tin cậy. Nhiều khung công tác đi kèm với tính năng này theo mặc định.

Tuy nhiên bạn chỉ có thể sử dụng JSON Web Tokens (jwt) với PHP để thêm ủy quyền api của bạn yêu cầu

Tìm hiểu xác thực về thẻ dựa từ this page.

Kiểm tra điều này simple tutorial về cách bảo mật điểm cuối api PHP của bạn với JWT.

Nếu bạn cần bảo mật hơn nữa, bạn có thể muốn thêm dịch vụ nhà cung cấp OAuth vào API của mình. hãy xem bài đăng này trên how to write OAuth provider in PHP

3

Phương pháp duy nhất để bảo mật api của bạn là yêu cầu Android của bạn trở nên độc đáo. Thu thập dữ liệu cụ thể hơn từ ứng dụng của bạn.

1 - Nhận Android Unique ID -

String UniqueID=Secure.getString(getActivity().getContentResolver(),Secure.ANDROID_ID); 

Và vượt qua nó thông qua api của bạn Ví dụ.

http://192.168.100.9:8000/MobileApp/GET_DATA.php?yourvalue=something&id=UniqueID 

Trong php của bạn, từ chối truy cập nếu không có ID duy nhất của Android (nên thay đổi bằng tên biến phức tạp).Ví dụ:

if($_REQUEST['UniqueID']=="" || strlen($_REQUEST['UniqueID'])<9){ //do something about abuse }else{ //your code } 

2 - Tạo biến ngẫu nhiên của riêng bạn trong Android App

Tạo biến của riêng bạn để quyết định để đảm bảo yêu cầu đến từ ứng dụng của bạn ví dụ:

Random r = new Random(); 
int i1 = r.nextInt(9999 - 1000) + 1000; 

Và cũng vượt qua giá trị này thông qua yêu cầu của bạn và xác nhận khi nói đến php.

if($_REQUEST['r']>=1000 && $_REQUEST['r']<=9999){//} 

Từ chối yêu cầu nếu không vượt qua hoặc sai giá trị.

3 - Đảm bảo các yêu cầu đến từ Android

Tôi muốn khuyên bạn nên sử dụng miễn phí thư viện php tốt nhất http://mobiledetect.net/ Kiểm tra cho dù đó là từ android và viết từ chối chức năng trên lạm dụng không hợp lệ.

4 - Xác nhận yêu cầu qua User-Agent chuỗi trong PHP

$agent = $_SERVER['HTTP_USER_AGENT']; 
$agent=strtolower($agent); 

if (strpos($agent, 'android') !== false) { 
$os = 'Android'; 
} 

Và từ chối nếu không phải từ Android trong php.

5 - Ghi lại những kẻ tấn công

Bạn cần phải theo dõi nếu có ai đó đang vi phạm một trong những chứng khoán trên của bạn. Hiện tại tôi đang sử dụng ip-api.com để theo dõi kẻ tấn công.

bạn cần phải viết chức năng từ chối bằng chèn mysql. theo ip-api, bạn sẽ nhận được ip
2- Những kẻ tấn công

1- Những kẻ tấn công geolocation ISP
3 Những kẻ tấn công

Vì vậy, bạn có thể từ chối họ tĩnh.

Đó là về để an toàn để sử dụng api của bạn từ android và gần như bị từ chối yêu cầu máy tính. Nhưng ba là một cơ hội để phá vỡ ứng dụng của bạn với kỹ thuật đảo ngược như dex2jar hoặc ShowJava và lấy cấu trúc dữ liệu đơn giản của bạn. Là một lập trình viên, các chức năng và mã trên rất dễ dàng đối với họ và họ sẽ gặp phải các đầu vào dữ liệu giả mạo.

Vì vậy, bạn không nên viết chương trình có giá trị tĩnh, liên kết quan trọng như vậy "http://192.168.100.9:8000/MobileApp/GET_DATA.php" được mã hóa cứng như trong ứng dụng của bạn. Bạn nên tách dữ liệu, mã hóa đơn giản và nhận tất cả các url chính của bạn động như trên phương thức php/mysql api được bảo mật.

Nếu bạn phủ sóng giống như hệ thống động 2 bước, có rất ít cơ hội để phá vỡ trong hệ thống của bạn.
Tôi có một điều quan trọng cần nói, nếu bạn đang sử dụng cho nhóm người dùng kín, bạn nên sử dụng hệ thống yêu cầu-> phê duyệt cho mỗi người dùng để đăng ký ứng dụng lần đầu tiên bằng cách sử dụng ID duy nhất của họ và dễ dàng từ chối truy cập từ những người khác.

0

bảo mật các API để được bên thứ ba truy cập là một miền rộng lớn cần thảo luận.Cơ chế được sử dụng nhiều nhất để bảo mật các API là kiểm soát truy cập dựa trên mã thông báo. Nó có thể được thực hiện theo nhiều cách.

Trước tiên, bạn cần hiểu cách hoạt động của nó. Tham khảo link và số link này.

Sau đó, hãy thử xem cách triển khai.

Working example of implementing 'Token Based Authentication' using 'JSON Web Token (i.e. JWT)' in PHP and MySQL?

Nếu bạn cần thêm sâu dụ thử link này là tốt.

Nếu bạn cần thêm thông tin, hãy cho tôi biết.

0

Sử dụng cơ chế kiểm soát phiên tất cả các phương pháp trên cũng đang nói cho cùng. Nói một cách đơn giản sử dụng khóa bí mật được mã hóa để phát hiện các nguồn hợp lệ

0
I will simply say, 

If you already using PHP OPP, then no need to go with any framework. It will be time consuming for you. 
Solution is: "Use remember_token system as like laravel and yii. Authenticate to each method before filter." 

If you are using Core PHP. Try same code and include it before filter each method in your api 
0

Bạn có thể chọn bạn xác thực cho PHP ở đây:

http://pear.php.net/packages.php?catpid=1&catname=Authentication

Tôi nghĩ rằng Basic hoặc Digest Auth (+ https: // SSL với chứng chỉ tự ký) sẽ được lựa chọn tốt cho bạn Rest-Service (PHP RESTful JSON API).

Đối với ứng dụng Android Tôi nghĩ rằng lựa chọn tốt nhất cho thư viện RestClient là:

http://square.github.io/retrofit/

(tôi khuyên bạn nên giữ cho tất cả các mã nguồn trong một ngôn ngữ duy nhất -Java Bạn dễ dàng có thể tạo Java Rest Service và thêm mùa xuân. Xác thực bảo mật)

Các vấn đề liên quan