私はAndroid開発に初心者です。アプリケーション開発にAndroid studio
を使用しています。
DB
に2つのテーブルを持つMySQL
を作成しました。GET
メソッドとPOST
メソッドの両方に対して2つの別個のapi's
を作成しました。api's
の両方に正常にアクセスしました私が今達成したこと
GET
からapi
データを作成できます。POST
を使用してapi
データが可能私が今しなければならないこと
APIをオンラインで公開します。つまり、サービスをサーバーに展開してアクセスします。この時点で、サーバーにサービスを展開してアクセスできます。
今、私は私のサービス(api's
)を保護したいです。そのために私は多くの記事を検索し、2つの方法を見つけました。
yii
フレームワークを使用します。 api's
を自動的に保護したため、誰かがそれを使用するように言った。しかし、私はそれがそうであるかどうか確かに知りません。api's
を手動で保護しますポイント1
に関しては、フレームワークは役立ちますが、私にとっては新しいものであり、すでにWebサービスを作成しているので、それと協力するには時間がかかります。
ポイント2
については、いくつかの情報があります
両方のリンクは良いように見えますが、リンク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 :(。私または私が従うチュートリアルを教えてください。
どんな助けも大歓迎です。
APIを保護するには、信頼されたソースからAPIへのリクエストが行われたことを検出するメカニズムが必要です。多くのフレームワークには、デフォルトでこの機能が付属しています。
ただし、 JSON Web Tokens(jwt) with PHPを使用して、APIリクエストに認証を追加できます
このページからトークンベースの認証について学びます。
JWTを使用してPHP apiエンドポイントを保護する方法については、こちら簡単なチュートリアルをご覧ください。
さらにセキュリティが必要な場合は、APIにOAuthプロバイダーサービスを追加することをお勧めします。この投稿は how OAuth provider PHPの場合
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システムを使用し、簡単にアクセスを拒否する必要があります。他人。
最初にビルドグラドル(アプリ)に依存関係を追加します
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);
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認証を追加します)
セッション制御メカニズムを使用して、上記のすべての方法でも同じことが言えます。簡単に言えば、暗号化された秘密キーを使用して有効なソースを検出します
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