Защита php api для использования в приложении Android

Я новичок в разработке Android. Я использую android studio для разработки приложения. Что я сделал

  1. Создал DB с двумя таблицами в нем в MySQL .
  2. Создал два отдельных api's для методов GET и POST .
  3. Успешно получили доступ как к api's

То, что я достиг в настоящее время

  1. Возможность получить данные из GET api .
  2. Возможность получения данных POST с использованием POST api

Что я должен сделать сейчас

Я хочу, чтобы мой api опубликовал в Интернете, то есть я хочу развернуть свои службы на сервере и получить к ним доступ. В этот момент я могу развернуть службы на сервере и получить к ним доступ.

Теперь я хочу, чтобы мои службы ( api's ) были защищены. Для этого я искал много статей и нашел два пути.

  1. Используйте структуру yii . Кто-то сказал мне использовать его, потому что он автоматически обеспечивал api's . Но я точно не знаю, делает это или нет.
  2. Вручную закрепите api's

Что касается пункта 1 структура будет полезна, но она для меня нова, и для ее взаимодействия потребуется время, так как я уже создал веб-службы.

Для пункта 2 я получил некоторую информацию

  1. используя HMAC_SHA1
  2. ОБНАРУЖЕНИЕ МОБИЛЬНЫХ УСТРОЙСТВ ИСПОЛЬЗОВАНИЕ PHP

Обе ссылки кажутся хорошими, но ссылка 1 не дает мне много информации об этом.

Очевидно, я хочу, чтобы обе свои api's

Теперь часть кода

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'] ));} 

echo json_encode (массив ('users' => $ result));

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; 

У меня есть user class из которого я получаю username и ID

JSONfunctions.java

Этот класс отвечает за получение данных из 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

Этот класс отвечает за метод POST

 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(""); } }); } } 

Поскольку я новичок, поэтому я не знаю, что делать в php скрипте и что делать в моем коде Android 🙁 Было бы очень полезно, если бы кто-нибудь мог направить меня или дать мне учебник, которым я следую.

Любая помощь будет высоко оценен.

Чтобы защитить ваши API, вам нужен механизм для обнаружения того, что запрос на api сделан из надежного источника. Многие фреймворки поставляются с этой функцией по умолчанию.

Однако вы можете просто использовать JSON Web Tokens (jwt) с PHP, чтобы добавить авторизацию к вашим запросам api

Узнайте об аутентификации на основе токенов с этой страницы .

Ознакомьтесь с этим простым учебным пособием о том, как защитить ваши конечные точки PHP api с помощью JWT.

Если вам нужна еще больше безопасности, вы можете добавить сервис провайдера OAuth в свой API. прочитайте этот пост о том, как написать OAuth-провайдер в PHP

Единственный способ защитить ваш api – сделать ваш запрос на андроид уникальным. Выберите более конкретные данные из вашего приложения.

1 – получить уникальный идентификатор Android –

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

И передайте это через ваш api Eg.

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

В вашем php запретите доступ, если нет уникального идентификатора Android (необходимо изменить с именем сложной переменной) .Eg:

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

2 – Создайте свою собственную случайную переменную в приложении Android

Создайте свою собственную переменную, чтобы решить, что запрос поступает из вашего приложения. Например:

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

А также передать это значение через ваш запрос и проверить, когда дело доходит до php.

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

Отклонить запрос, если он не прошел или неправильно.

3 – Убедитесь, что запросы поступают с Android

Я хочу порекомендовать использовать бесплатную библиотеку php http://mobiledetect.net/. Проверьте, не работает ли она от android и не работает функция deny при неправильных злоупотреблениях.

4 – Проверка запроса через строку User-Agent в PHP

 $agent = $_SERVER['HTTP_USER_AGENT']; $agent=strtolower($agent); if (strpos($agent, 'android') !== false) { $os = 'Android'; } 

И отрицать, если не от android в php.

5 – Записать нападавших

Вам нужно отслеживать, нарушает ли кто-то один из ваших ценных бумаг. В настоящее время я использую ip-api.com для отслеживания злоумышленников.

вам нужно написать функцию deny с вставкой mysql. согласно ip-api, вы получите

1-й атакующий
2- геолокация атакующих
3-й интернет-провайдер

Таким образом, вы можете отрицать их статически.

Он собирается безопасно использовать ваш api из Android и почти отказал в запросах ПК. Но три – это шанс разорвать ваше приложение с помощью обратной инженерии, такой как dex2jar или ShowJava, и захватить вашу простую структуру данных. Как программист, выше функции и коды очень легки для них, и они будут работать с поддельными входами данных.

Поэтому вам не следует писать программу со статическими значениями, такую ​​важную ссылку « http://192.168.100.9:8000/MobileApp/GET_DATA.php » как жестко закодированную, как в вашем приложении. Вы должны разделить данные, просто зашифровать и получить все ваши основные URL-адреса динамически, как описано выше, с помощью метода php / mysql api.

Если вы используете как двухступенчатую динамическую систему, очень мало шансов переломить вашу систему.
Я хочу сказать, что если вы используете закрытую группу пользователей, вы должны использовать систему request-> approve для каждого пользователя для первой регистрации приложений, используя свой уникальный идентификатор и легко отказывать в доступе от других пользователей.

защищать API-интерфейсы для доступа третьей стороной – это обширный домен, который будет обсуждаться. Наиболее часто используемый механизм защиты API-интерфейсов – это контроль доступа на основе токенов. Его можно реализовать разными способами.

1-й вам нужно понять, как это работает. См. Эту ссылку и эту ссылку .

Затем попробуйте посмотреть, как его реализовать.

Рабочий пример реализации «Аутентификация на основе токенов» с использованием «JSON Web Token (т.е. JWT)» в PHP и MySQL?

Если вам нужен более подробный пример, попробуйте эту ссылку .

Если вам нужна дополнительная информация, дайте мне знать.

Используйте механизм управления сеансом, все описанные выше методы также говорят об этом. В простых словах используется зашифрованный закрытый ключ для обнаружения действительного источника

 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 

Вы можете выбрать аутентификацию для PHP здесь:

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

Я думаю, что Basic или Digest Auth (+ https: // SSL с самоподписанным сертификатом) будет хорошим выбором для вас Rest-Service (PHP RESTful JSON API).

Для Android-приложения я считаю, что лучше всего выбрать для библиотеки RestClient:

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

(Я рекомендую вам сохранить весь исходный код только на одном языке -Java. Вы можете легко создать службу восстановления Java и добавить Spring Security Authentication)