我正在创建一个始终调用服务器来加载数据(JSON数据)的应用程序。 像谷歌api我怎样才能确保POST请求来自我的Android应用程序。 如何确保?
我的代码我总是将POST请求发送到php服务器,如下所示
以下代码将电话和密码等数据发送到登录状态 但如果有人从我的Android应用程序复制这个并在他们的应用程序中使用。然后服务器将被黑客入侵。如何阻止仅从我的Android应用程序接受POST请求,而不是来自任何其他来源。
StringRequest stringRequest = new StringRequest(Request.Method.POST, REQ_URL, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Toast.makeText(HomeActivity.this, "" + response , Toast.LENGTH_LONG).show();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
String message = null;
if (error instanceof TimeoutError || error instanceof NoConnectionError) {
message=("Network Timeout Error");}
else if (error instanceof AuthFailureError) {
message=("Authentication Failure");}
else if (error instanceof ServerError) {
message=("Server Error");}
else if (error instanceof NetworkError) {
message=("Network Error");}
else if (error instanceof ParseError) {
message=("Network Timeout Error");}
error.printStackTrace();
Toast.makeText(HomeActivity.this, "" + message , Toast.LENGTH_LONG).show();
}
}) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("reqtype", "login");
params.put("phone", phone);
params.put("pass", password);
return params;
}
};
int socketTimeout = 15000;//30 seconds - change to what you want
RetryPolicy policy = new DefaultRetryPolicy(socketTimeout, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
stringRequest.setRetryPolicy(policy);
ServerRequest.getInstance(HomeActivity.this).addtoRequestQue(stringRequest);
答案 0 :(得分:1)
因此需要首先学习用于Android的SSL,并且需要在服务器端创建SSL证书。
<强>概念强>
在典型的SSL使用方案中,服务器配置了一个 包含公钥和匹配私钥的证书。 作为SSL客户端和服务器之间握手的一部分,服务器 通过签署证书证明它有私钥 public-key加密。
以下示例将使这些概念更加具体。 在命令行下面的代码片段中,openssl工具的s_client 命令查看Wikipedia的服务器证书信息。它 指定端口443,因为这是HTTPS的默认值。命令 将openssl s_client的输出发送到openssl x509,格式化 有关根据X.509标准的证书的信息。 具体来说,该命令要求包含该主题的主题 服务器名称信息和标识CA的颁发者。
$ openssl s_client -connect wikipedia.org:443 | openssl x509 -noout -subject -issuer
subject= /serialNumber=sOrr2rKpMVP70Z6E9BT5reY008SJEdYv/C=US/O=*.wikipedia.org/OU=GT03314600/OU=See www.rapidssl.com/resources/cps (c)11/OU=Domain Control Validated - RapidSSL(R)/CN=*.wikipedia.org
issuer= /C=US/O=GeoTrust, Inc./CN=RapidSSL CA
不需要在下面编写代码,如下所示: -
public static SSLContext getSSLContextObject() {
if (sslContext == null) {
InputStream certificateInputStream = null;
CertificateFactory certificateFactory = null;
Certificate certificate = null;
String keyStoreType = null;
KeyStore keyStore = null;
String trustManagerAlgorithm = null;
TrustManagerFactory trustManagerFactory = null;
try {
certificateFactory = CertificateFactory.getInstance("X.509");
certificateInputStream = new BufferedInputStream(FliplearnApp
.getInstance().getAssets().open("certificateName.any.crt"));
try {
certificate = certificateFactory
.generateCertificate(certificateInputStream);
} finally {
certificateInputStream.close();
}
// Create a KeyStore containing our trusted CAs
keyStoreType = KeyStore.getDefaultType();
keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("certificate", certificate);
// Create a TrustManager that trusts the CAs in our KeyStore
trustManagerAlgorithm = TrustManagerFactory
.getDefaultAlgorithm();
trustManagerFactory = TrustManagerFactory
.getInstance(trustManagerAlgorithm);
trustManagerFactory.init(keyStore);
// Create an SSLContext that uses our TrustManager
sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustManagerFactory.getTrustManagers(),
null);
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
}
return sslContext;
}
不需要使用如下所示的SSL上下文对象编写代码: -
public class Api {
private SSLContext sslContext;
private int lastResponseCode;
public int getLastResponseCode() {
return lastResponseCode;
}
public Api(AuthenticationParameters authParams) throws Exception {
File clientCertFile = authParams.getClientCertificate();
sslContext = getSSLContextObject();
CookieHandler.setDefault(new CookieManager());
}
public String doGet(String url) throws Exception {
String result = null;
HttpURLConnection urlConnection = null;
try {
URL requestedUrl = new URL(url);
urlConnection = (HttpURLConnection) requestedUrl.openConnection();
if(urlConnection instanceof HttpsURLConnection) {
((HttpsURLConnection)urlConnection).setSSLSocketFactory(sslContext.getSocketFactory());
}
urlConnection.setRequestMethod("GET");
urlConnection.setConnectTimeout(1500);
urlConnection.setReadTimeout(1500);
lastResponseCode = urlConnection.getResponseCode();
result = IOUtil.readFully(urlConnection.getInputStream());
} catch(Exception ex) {
result = ex.toString();
} finally {
if(urlConnection != null) {
urlConnection.disconnect();
}
}
return result;
}
}
现在您需要将上面的代码集成到您的排球中。
答案 1 :(得分:0)
您可以将设备类型甚至设备ID作为网络呼叫的标头参数发送。因此,在服务器端,您可以验证标头中发送的设备和标识是否为android或其他,因此可以访问或不可访问。这有帮助吗?