如何使用Java HttpClient库使用PHP上传文件(How to upload a file using Java HttpClient library working with PHP)
我想编写将使用PHP将文件上传到Apache服务器的Java应用程序。 Java代码使用Jakarta HttpClient库4.0版beta2:
import java.io.File; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.FileEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.CoreProtocolPNames; import org.apache.http.util.EntityUtils; public class PostFile { public static void main(String[] args) throws Exception { HttpClient httpclient = new DefaultHttpClient(); httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1); HttpPost httppost = new HttpPost("http://localhost:9002/upload.php"); File file = new File("c:/TRASH/zaba_1.jpg"); FileEntity reqEntity = new FileEntity(file, "binary/octet-stream"); httppost.setEntity(reqEntity); reqEntity.setContentType("binary/octet-stream"); System.out.println("executing request " + httppost.getRequestLine()); HttpResponse response = httpclient.execute(httppost); HttpEntity resEntity = response.getEntity(); System.out.println(response.getStatusLine()); if (resEntity != null) { System.out.println(EntityUtils.toString(resEntity)); } if (resEntity != null) { resEntity.consumeContent(); } httpclient.getConnectionManager().shutdown(); } }
PHP文件
upload.php
很简单:<?php if (is_uploaded_file($_FILES['userfile']['tmp_name'])) { echo "File ". $_FILES['userfile']['name'] ." uploaded successfully.\n"; move_uploaded_file ($_FILES['userfile'] ['tmp_name'], $_FILES['userfile'] ['name']); } else { echo "Possible file upload attack: "; echo "filename '". $_FILES['userfile']['tmp_name'] . "'."; print_r($_FILES); } ?>
阅读回复我得到以下结果:
executing request POST http://localhost:9002/upload.php HTTP/1.1
HTTP/1.1 200 OK Possible file upload attack: filename ''. Array ( )所以请求是成功的,我能够与服务器通信,但是PHP没有注意到该文件 - 方法
is_uploaded_file
返回false
,$_FILES
变量为空。 我不知道为什么这可能会发生。 我跟踪了HTTP响应和请求,他们看起来很好:
要求是:POST /upload.php HTTP/1.1 Content-Length: 13091 Content-Type: binary/octet-stream Host: localhost:9002 Connection: Keep-Alive User-Agent: Apache-HttpClient/4.0-beta2 (java 1.5) Expect: 100-Continue ˙Ř˙ŕ..... the rest of the binary file...和回应:
HTTP/1.1 100 Continue HTTP/1.1 200 OK Date: Wed, 01 Jul 2009 06:51:57 GMT Server: Apache/2.2.8 (Win32) DAV/2 mod_ssl/2.2.8 OpenSSL/0.9.8g mod_autoindex_color PHP/5.2.5 mod_jk/1.2.26 X-Powered-By: PHP/5.2.5 Content-Length: 51 Keep-Alive: timeout=5, max=100 Connection: Keep-Alive Content-Type: text/html Possible file upload attack: filename ''.Array ( )我正在使用xampp和远程Linux服务器在本地Windows XP上测试这一点。 我也尝试使用以前版本的HttpClient - 3.1版,结果更加不清楚,
is_uploaded_file
返回false
,但$_FILES
数组已填充正确的数据。I want to write Java application that will upload a file to the Apache server with PHP. The Java code uses Jakarta HttpClient library version 4.0 beta2:
import java.io.File; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.FileEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.CoreProtocolPNames; import org.apache.http.util.EntityUtils; public class PostFile { public static void main(String[] args) throws Exception { HttpClient httpclient = new DefaultHttpClient(); httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1); HttpPost httppost = new HttpPost("http://localhost:9002/upload.php"); File file = new File("c:/TRASH/zaba_1.jpg"); FileEntity reqEntity = new FileEntity(file, "binary/octet-stream"); httppost.setEntity(reqEntity); reqEntity.setContentType("binary/octet-stream"); System.out.println("executing request " + httppost.getRequestLine()); HttpResponse response = httpclient.execute(httppost); HttpEntity resEntity = response.getEntity(); System.out.println(response.getStatusLine()); if (resEntity != null) { System.out.println(EntityUtils.toString(resEntity)); } if (resEntity != null) { resEntity.consumeContent(); } httpclient.getConnectionManager().shutdown(); } }
The PHP file
upload.php
is very simple:<?php if (is_uploaded_file($_FILES['userfile']['tmp_name'])) { echo "File ". $_FILES['userfile']['name'] ." uploaded successfully.\n"; move_uploaded_file ($_FILES['userfile'] ['tmp_name'], $_FILES['userfile'] ['name']); } else { echo "Possible file upload attack: "; echo "filename '". $_FILES['userfile']['tmp_name'] . "'."; print_r($_FILES); } ?>
Reading the response I get the following result:
executing request POST http://localhost:9002/upload.php HTTP/1.1
HTTP/1.1 200 OK Possible file upload attack: filename ''. Array ( )So the request was successful, I was able to communicate with server, however PHP didn't notice the file - the method
is_uploaded_file
returnedfalse
and$_FILES
variable is empty. I have no idea why this might happend. I have tracked HTTP response and request and they look ok:
request is:POST /upload.php HTTP/1.1 Content-Length: 13091 Content-Type: binary/octet-stream Host: localhost:9002 Connection: Keep-Alive User-Agent: Apache-HttpClient/4.0-beta2 (java 1.5) Expect: 100-Continue ˙Ř˙ŕ..... the rest of the binary file...and response:
HTTP/1.1 100 Continue HTTP/1.1 200 OK Date: Wed, 01 Jul 2009 06:51:57 GMT Server: Apache/2.2.8 (Win32) DAV/2 mod_ssl/2.2.8 OpenSSL/0.9.8g mod_autoindex_color PHP/5.2.5 mod_jk/1.2.26 X-Powered-By: PHP/5.2.5 Content-Length: 51 Keep-Alive: timeout=5, max=100 Connection: Keep-Alive Content-Type: text/html Possible file upload attack: filename ''.Array ( )I was testing this both on the local windows xp with xampp and remote Linux server. I have also tried to use previous version of HttpClient - version 3.1 - and the result was even more unclear,
is_uploaded_file
returnedfalse
, however$_FILES
array was filled with proper data.
原文:https://stackoverflow.com/questions/1067655
最满意答案
不熟悉Facebook API和iOS,所以我完全用理论来讲。
你能不能:
- 要求用户在iOS应用程序上使用Facebook登录
- 通过安全通道将登录数据发送到Web应用程序,以处理数据的实际处理
- 向iOS应用程序发送安全哈希以进行身份验证
- 根据需要使用您的Web应用程序; 使用哈希进行身份验证,像对待Web应用程序一样发出HTTPS请求,并使用来自Web服务器的响应来填充iOS应用程序
如果您将
user_hash
列设置为SHA-256(或更高版本)哈希之类的复杂盐渍哈希,则user_hash将在任何人能够猜测哈希值之前变为无效。 您可以在iOS设备上本地保存用户的Facebook凭据,然后每隔一段时间更新一次哈希,以使旧哈希失效并锁定犯罪者(如cookie过期)。 如果用户哈希在使用iOS应用程序时以某种方式变为无效,则应用程序将发送本地存储的凭据并检索新凭据。如果Apple为应用程序提供cookie,您可以从您的网页发送cookie并给它一个合理的到期时间(例如1天)。 您每天都会重新发送本地存储的Facebook凭据,并有效地锁定任何试图破坏您的哈希值的人。 使用它而不是尝试从头开始实现cookie(如果iOS API提供),但正如我所说,我不熟悉iOS。
从SQL的角度来看,您的网页将验证用户的Facebook凭据,创建一个带有随机生成的
user_hash
的新行,expires
timestamp,user_id
,friends_id
等。每个使用该网页的用户都必须从他们的网站发送user_hash
客户端或iOS应用程序将根据数据库进行检查。 如果当前时间戳超过expires
时间戳,则会话被裁定为无效,并且用户无法操作您的应用程序。当然,您需要加密通信。 每次用户在Web应用程序上加载页面时,您是否都会传递凭据? 或者你把它们存放在会话中?
希望这至少有点帮助!
Not familiar with the Facebook API nor iOS so I am speaking completely in theoretical terms.
Could you not:
- Ask the user to login with Facebook on the iOS app
- Send the login data over a secure channel to your web application to handle the actual processing of the data
- Send the iOS app a secure hash for authentication
- Use your web application as needed; using the hash for authentication, make HTTPS requests as you would your web application and use the responses from the webserver to populate the iOS app
If you make a
user_hash
column a complex salted hash like a SHA-256 (or greater) hash, the user_hash will become invalid before anybody is able to guess the hash. You could save the user's Facebook credentials locally on the iOS device and then renew the hash every so often, as to invalidate old hashes and lock out perpetrators (like how a cookie expires). If the user hash somehow becomes invalidated while using the iOS app, the app will send the locally stored credentials and retrieve a new one.If Apple offers cookies for apps, you could send the hash in a cookie from your webpage and give it a reasonable expiry time (e.g. 1 day). You'd be resending the locally stored Facebook credentials every day and be effectively locking out anybody trying to bruteforce your hashes. Use that instead of trying to implement cookies from scratch (if the iOS API offers that), but as I said, I'm unfamiliar with iOS.
From an SQL standpoint, your webpage would validate a user's Facebook credentials, create a new row with a randomly generated
user_hash
,expires
timestamp,user_id
,friends_id
, etc. Every user that uses the webpage will have to send theuser_hash
either from their web-client or the iOS app and will be checked against the database. If the present timestamp exceeds theexpires
timestamp, the session is ruled invalid and the user cannot operate your application.Of course, you'd need to encrypt the communication. Do you pass credentials everytime the user loads a page on your web app? Or do you store them in a session?
Hope this helps at least somewhat!
相关问答
更多-
不熟悉Facebook API和iOS,所以我完全用理论来讲。 你能不能: 要求用户在iOS应用程序上使用Facebook登录 通过安全通道将登录数据发送到Web应用程序,以处理数据的实际处理 向iOS应用程序发送安全哈希以进行身份验证 根据需要使用您的Web应用程序; 使用哈希进行身份验证,像对待Web应用程序一样发出HTTPS请求,并使用来自Web服务器的响应来填充iOS应用程序 如果您将user_hash列设置为SHA-256(或更高版本)哈希之类的复杂盐渍哈希,则user_hash将在任何人能够猜测 ...
-
首先我想强调认证和授权之间的区别: 用户通过提供一些凭证(如用户名+密码)向您的网站进行身份验证。 OpenID允许通过让用户向另一个服务进行身份验证来取代这个服务,然后用户代表用户将其身份标识给您的网站。 您的网站信任第三方服务(OpenID Provider),因此认为用户已登录。 服务或应用程序不会对您的网站进行身份验证 - 至少通常不会。 用户授权服务或应用程序访问用户的数据。 这通常由请求服务提供商的授权的应用程序完成,然后将用户发送到用户首先进行认证的服务提供商(因此服务提供商知道其与谁通话), ...
-
从第三方隐藏API密钥?(Hide API key from 3rd party?)[2021-12-24]
我前几天就Google Maps API密钥问了一个类似的问题 。 我的想法是,是否值得担心有人使用我的通话津贴。 一致认为,API旨在以这种方式使用,并且您无法做很多事情。 如果你的API要求你的域名作为带有API密钥的引用者标题(Google地图确实如此),那我认为这提供了一定程度的威慑力。 I asked a similar question the other day with regards to the Google Maps API key. My thought was whether it ... -
IdentityServer3是用于构建SSO解决方案的框架。 https://identityserver.github.io/Documentation/ IdentityServer3 is a framework for building SSO solutions. https://identityserver.github.io/Documentation/
-
如何成为贝宝用户可以授予API访问权限的PayPal第三方(How to become PayPal's 3rd party which paypal users can grant API access to)[2022-03-24]
要授予任何第三方许可(例如您希望向开发人员提供API权限),那么您的第三方(开发人员)需要创建一个PayPal帐户并请求API凭据(通过登录他/她的PayPal帐户)为了向您的第三方授予权限,您需要输入第三方(开发人员)API用户名(开发人员的API用户名)以授予权限。 To give permission to any third party(such as you want to give API permissions to your developer), then your third party ... -
401是要走的路。 RFC2616的两个摘录定义了HTTP协议: 第10.4.2节(约401): 如果请求已包含授权凭据,则401响应表示已拒绝这些凭据的授权。 这似乎适用于过期的令牌。 有身份验证凭据,但它们被拒绝,因此用户代理必须重新进行身份验证。 第10.4.4节(约403): 服务器理解请求,但拒绝履行请求。 授权无效,请求不应重复。 尽管用户凭据无法访问资源,但应使用此方法。 可能是一个网站/ API,仅适用于被亚洲IP或已声明有害且已停用的网页击中的美国(因此内容已找到,但服务器拒绝提供服务)。 ...
-
绝对是的! 它被称为two legged authentification (它与存储在授权服务器数据库中的用户凭证一起使用)。 它意味着你的客户端应用程序和你的资源服务器)你可以在这里查看一些文档: http://blog.nerdbank.net/2011/06/what-is-2-legged-oauth.html http://oauthbible.com/ 和官方规范(第10页上,您可以看到我用于我的应用程序的工作流程): https : //tools.ietf.org/html/rfc6749 ...
-
您是否在Ember.SimpleAuth仓库中看过Facebook示例( https://github.com/simplabs/ember-simple-auth/blob/master/examples/7-external-oauth/index.html )? 基本概念是Ember.js应用程序打开Facebook Auth UI,然后重定向到您的应用程序(在服务器端)处理Facebook的响应,并可能将Facebook的令牌替换为Ember.js应用程序可用于验证的自定义令牌对你的服务器。 Hav ...
-
Google Fonts提供了3种在页面上包含字体的方法:通过link元素,CSS @import语句和外部JavaScript。 如果使用link属性设置为“text / css”或通过css @import语句包含样式表,则应该没有安全问题; 浏览器只会尝试将其作为CSS读取并忽略任何无效的内容。 通过外部JavaScript包含字体会有潜在的安全风险,但这一切都归结为信任; 您信任Google或Adobe为您托管JavaScript吗? Google Fonts offers 3 methods of ...
-
说明显而易见的:重要的是,当然不要让您网站上的攻击者访问所有cookie。 您无法完全防范这种情况,因为您的服务需要定期访问Cookie(以未加密的形式)。 理论上,攻击者完全破坏了您的服务器将能够执行您的服务可以执行的任何操作,因此,如果您的服务可以访问cookie,那么拥有所有权限的攻击者也将能够访问他们。 如果你还想这样做,你应该这样做 1)使攻击者更难以访问cookie 只是为了举例说明如何考虑这个问题:如果您的系统遭到入侵,攻击者很可能会访问您的文件系统。 如果cookie以纯文本形式存储在文件中 ...