web-dev-qa-db-ja.com

Androidアプリケーションで使用するPHP APIの保護

私はAndroid開発に初心者です。アプリケーション開発にAndroid studioを使用しています。

  1. DBに2つのテーブルを持つMySQLを作成しました。
  2. GETメソッドとPOSTメソッドの両方に対して2つの別個のapi'sを作成しました。
  3. api'sの両方に正常にアクセスしました

私が今達成したこと

  1. GET GETからapiデータを作成できます。
  2. POST POSTを使用してapiデータが可能

私が今しなければならないこと

APIをオンラインで公開します。つまり、サービスをサーバーに展開してアクセスします。この時点で、サーバーにサービスを展開してアクセスできます。

今、私は私のサービス(api's)を保護したいです。そのために私は多くの記事を検索し、2つの方法を見つけました。

  1. yiiフレームワークを使用します。 api'sを自動的に保護したため、誰かがそれを使用するように言った。しかし、私はそれがそうであるかどうか確かに知りません。
  2. api'sを手動で保護します

ポイント1に関しては、フレームワークは役立ちますが、私にとっては新しいものであり、すでにWebサービスを作成しているので、それと協力するには時間がかかります。

ポイント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(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;

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 code :(。私または私が従うチュートリアルを教えてください。

どんな助けも大歓迎です。

20
Moeez

APIを保護するには、信頼されたソースからAPIへのリクエストが行われたことを検出するメカニズムが必要です。多くのフレームワークには、デフォルトでこの機能が付属しています。

ただし、 JSON Web Tokens(jwt) with PHPを使用して、APIリクエストに認証を追加できます

このページからトークンベースの認証について学びます。

JWTを使用してPHP apiエンドポイントを保護する方法については、こちら簡単なチュートリアルをご覧ください。

さらにセキュリティが必要な場合は、APIにOAuthプロバイダーサービスを追加することをお勧めします。この投稿は how OAuth provider PHPの場合

12
Dani Akash

Apiを保護する唯一の方法は、Androidを一意に要求することです。アプリからより具体的なデータを収集します。

1-Get Android一意のID-

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一意のID(複雑な変数名で変更する必要があります)がない場合、アクセスを拒否します。

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

2-Android Appで独自のランダム変数を作成します

独自の変数を作成して、アプリからのリクエストであることを確認します。例:

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からのものであるかどうかを確認し、無効な不正行為に対して拒否関数を記述します。

4-PHPのUser-Agent文字列を介したリクエストの検証

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

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

そうでない場合は、Androidのphp。

5-攻撃者を記録する

誰かが上記の証券のいずれかを破っているかどうかを追跡する必要があります。現在、攻撃者を追跡するために ip-api.com を使用しています。

mysql insertで拒否関数を作成する必要があります。 ip-apiによると、あなたは得るでしょう

1-攻撃者のIP
2-攻撃者の位置情報
3-攻撃者のISP

したがって、それらを静的に拒否できます。

Androidからapiを使用して、PCリクエストをほぼ拒否しました。しかし、3つは、dex2jarやShowJavaのようなリバースエンジニアリングでアプリを中断し、単純なデータ構造を取得するチャンスです。プログラマーにとって、上記の関数とコードは非常に簡単であり、偽のデータ入力を受け入れます。

したがって、静的な値を持つプログラムを書くべきではありません。そのような重要なリンク「 http://192.168.100.9:8000/MobileApp/GET_DATA.php 」は、アプリのようにハードコードされています。上記の保護されたphp/mysql apiメソッドのように、データを分割し、単純な暗号化を行い、すべてのメインURLを動的に取得する必要があります。

2ステップの動的システムのようにカバーした場合、システムに侵入する可能性はほとんどありません。
閉じたユーザーグループに使用している場合は、一意のIDを使用して初めてア​​プリを登録するために各ユーザーにrequest-> approveシステムを使用し、簡単にアクセスを拒否する必要があります。他人。

2
Aung Aung Swe

最初にビルドグラドル(アプリ)に依存関係を追加します
implementation 'com.mcxiaoke.volley:library:1.0.16'その後、以下のコードに従います。

 final ProgressDialog loading = ProgressDialog.show(getActivity(), "", "Please wait...", false, false);
        StringRequest stringRequest = new StringRequest(Request.Method.POST, ServerLinks.TOTAL_COUNT_URL, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                loading.dismiss();
                try {
                    JSONObject jsonObject = new JSONObject(response);

                    String status = jsonObject.getString("status");

                    if (status.equals("success")) {
                        String data = jsonObject.getString("data");

                        JSONObject jsonObject1 = new JSONObject(data);
                        String male = jsonObject1.getString("male");
                        String female = jsonObject1.getString("female");


                    } else {
                        // no_data_found.setVisibility(View.VISIBLE);
                        Toast.makeText(getActivity(), "No Data Found", Toast.LENGTH_SHORT).show();
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }//onResponse()
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                loading.dismiss();
                //Toast.makeText(getActivity(), "Check Your Internet Connection", Toast.LENGTH_SHORT).show();
            }
        });
        int socketTimeout = 30000; // 30 seconds. You can change it
        RetryPolicy policy = new DefaultRetryPolicy(socketTimeout,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);

        stringRequest.setRetryPolicy(policy);
        RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
        requestQueue.add(stringRequest);
0
Rock Mihar

PHPここの認証:

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

基本認証またはダイジェスト認証(+ https:// SSL、自己署名証明書)は、Rest-Service(PHP RESTful JSON API)に適していると思います。

Android applicationの場合、RestClientライブラリに最適な選択肢は次のとおりです。

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

(すべてのソースコードを1つの言語でのみ保持することをお勧めします。Java。簡単に作成できます Java Rest Service およびSpring Security認証を追加します)

0
sytolk

セッション制御メカニズムを使用して、上記のすべての方法でも同じことが言えます。簡単に言えば、暗号化された秘密キーを使用して有効なソースを検出します

0
Kushaal Singla
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
Heartbeat