Como proteger o php api para usar na aplicação Android

Eu sou novato no desenvolvimento do Android. Estou usando o android studio para desenvolver um aplicativo. Coisas que fiz

  1. Criou um DB com duas tabelas no MySQL .
  2. Criou duas api's separadas para os methods GET e POST .
  3. Acessou com sucesso as duas api's

O que eu consegui por agora

  1. Capaz de obter dados da GET api .
  2. Capaz de POST dados usando POST api

O que eu tenho que fazer agora

Quero que minha api publique online, ou seja, quero implantar meus serviços em um servidor e acessá-los. Neste ponto, sou capaz de implantar os serviços no servidor e acessá-los.

Agora eu quero que meus serviços ( api's ) sejam protegidos. Por isso, procurei muitos artigos e encontrei duas maneiras.

  1. Use o framework yii . Alguém me disse para usá-lo porque garantiu automaticamente os api's . Mas eu não sei com certeza se o faz ou não.
  2. Proteja manualmente o api's

Quanto ao ponto 1 o quadro será útil, mas é novidade para mim, e levará tempo para cooperar com ele, já que já criei os serviços da web.

Para o ponto 2 recebi algumas informações

  1. usando HMAC_SHA1
  2. DETECER DISPOSITIVOS MÓVEIS USANDO PHP

Ambos os links parecem ser bons, mas o link 1 não me dá muita informação sobre isso.

Obviamente eu quero proteger minhas duas api's

Agora, a parte do código

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 (array (‘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; 

Eu tenho uma user class partir da qual eu estou recebendo username e ID

JSONfunctions.java

Esta class é responsável por obter dados da 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

Esta class é responsável pelo método 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 { @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(); // Create an array to populate the spinner userList = new ArrayList(); // 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(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(""); } }); } } 

Como sou novato, então não sei o que fazer no script php e o que fazer no meu código Android :(. Seria muito útil se alguém puder me guiar ou me dar um tutorial que eu acompanhe.

Qualquer ajuda será muito apreciada.

Para proteger suas APIs, você precisa de um mecanismo para detectar que a solicitação para a api é feita a partir de uma fonte confiável. Muitos frameworks vêm com esse recurso por padrão.

No entanto, você pode usar JSON Web Tokens (jwt) com PHP para adicionar autorização aos seus pedidos de api

Saiba mais sobre a autenticação baseada em token desta página .

Confira este tutorial simples sobre como proteger seus pontos de extremidade api do PHP com o JWT.

Se você precisar de mais segurança, você pode querer adicionar o serviço do provedor OAuth à sua API. Confira esta publicação sobre como escrever o provedor OAuth em PHP

O único método para proteger sua api é fazer sua solicitação do Android ser única. Colecione dados mais específicos do seu aplicativo.

1 – Obtenha Android Unique ID –

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

E passá-lo através do seu api, por exemplo.

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

No seu php, negue o access se não houver ID exclusiva do Android (deve mudar com o nome da variável complexa) .Eg:

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

2 - Crie sua própria variável aleatória no Android

Crie sua própria variável para decidir se a solicitação vem do seu aplicativo, por exemplo:

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

E também passar este valor através do seu pedido e validar quando se trata de php.

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

Negar pedido se não passar ou valor errado.

3 - Certifique-se de que os pedidos provêm do Android

Eu quero recomendar a usar a melhor biblioteca php grátis http://mobiledetect.net/ Verifique se é de android e escreva negar a function em abusos inválidos.

4 - Valide o pedido via string User-Agent em PHP

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

E negar se não do Android no php.

5 - Registre os atacantes

Você precisa rastrear se alguém está quebrando um de seus títulos acima. Atualmente uso ip-api.com para rastrear atacantes.

você precisa escrever negar function com mysql insert. de acordo com ip-api, você receberá

1- ip dos atacantes
2- Geolocalização dos atacantes
3- ISP dos atacantes

Então você pode negá-los de forma estática.

Está prestes a usar seu api de maneira segura e quase negado. Mas três é uma chance de quebrar o seu aplicativo com engenharia reversa, como dex2jar ou ShowJava e pegue sua estrutura de dados simples. Como programador, as funções e códigos acima são muito fáceis para eles e eles entrarão com inputs de dados falsas.

Então, você não deve escrever um programa com valores estáticos, importante link " http://192.168.100.9:8000/MobileApp/GET_DATA.php " como codificado como no seu aplicativo. Você deve dividir os dados, criptografar e obter todas as suas URLs principais de forma dinâmica, como acima do método seguro php / mysql api.

Se você cobriu exatamente como o sistema dynamic de 2 passos, há muito poucas chances de quebrar seu sistema.
Eu tenho um importante para dizer, se você estiver usando para grupo fechado de usuários, você deve usar o sistema de solicitação-> aprovar para cada usuário para o registro de aplicativos pela primeira vez, usando sua ID exclusiva e negando facilmente o access dos outros.

Proteger as APIs para ser acessado por um terceiro é um vasto domínio a ser discutido. O mecanismo mais usado para proteger as APIs é o controle de access baseado em token. Pode ser implementado de várias maneiras.

Primeiro você precisa entender como funciona. Consulte este link e este link .

Em seguida, tente olhar como implementá-lo.

Exemplo de trabalho de implementar ‘Autenticação baseada em Token’ usando ‘JSON Web Token (ie JWT)’ em PHP e MySQL?

Se você precisar de um exemplo mais aprofundado, tente este link também.

Se você precisar de mais informações, avise-me.

Use o mecanismo de controle de session todos os methods acima também estão falando pelo mesmo. Em palavras simples, use uma chave privada criptografada para detectar a fonte válida

 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 

Você pode escolher sua Autenticação para PHP aqui:

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

Eu acho que Basic ou Digest Auth (+ https: // SSL com certificado auto assinado) será bom para você Rest-Service (PHP RESTful JSON API).

Para o aplicativo Android, acho que a melhor escolha para a biblioteca do RestClient é:

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

(Eu recomendo que você mantenha todo o código-fonte em uma única língua -Java. Você pode criar o Java Rest Service e adicionar Spring Security Authentication)