网页上的一些事——拒绝“坏人”
来源:互联网 发布:2015手机淘宝最新版 编辑:程序博客网 时间:2024/04/30 20:12
网页防盗链
防盗链的概念:
网页显示的内容不在自己服务器上,而通过技术手段,绕过别人放广告有利益的最终页,直接在自己的有广告有利益的页面上向最终用户提供此内容,这样没有任何资源的网站利用了别的网站的资源来展示给浏览者,提高了自己的访问量,而大部分浏览者又不会很容易地发现,这样显然,对于那个被利用了资源的网站是不公平的。
盗链常见种类:图片盗链和文件盗链。
盗链防止办法:
1、基于http协议头中的referer头字段,通过该字段可以知道引用网站的网址,而通过判断该引用网站是否合法便可以阻止盗链现象。
如:有这么个链接:
<a href="http://localhost:8080/fday06/servlet/DemoServlet">凤姐最新消息</a>
所链接到的网站的首页为:
<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
</head>
<body>
广告。。。。。。。。。
<a href="/fday06/servlet/DemoServlet">惊爆凤姐最新消息.................</a>
</body>
</html>
链接到的DemoServlet的内容:
package cn.itcast.request;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@SuppressWarnings("serial")
public class DemoServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/Demo.jsp").forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
此时随便任何网站通过一个连接地址指向DemoServlet便可以盗走该网站的信息,而浏览者则毫不知情,要解决这个情况可将DemoServlet的doGet()方法修改为:
String referer=request.getHeader("referer");
//referer为null之浏览器通过地址直接访问,
//referer不是http://localhost则指为从别的网站链接而来
//以上两种情况下均使页面跳转到本网站首页
if(referer==null||!referer.startsWith("http://localhost")){
response.sendRedirect("/fday06/index.jsp");
return ;
}
request.getRequestDispatcher("/WEB-INF/Demo.jsp").forward(request, response);
2、通过自定义标签技术防盗链:
首页代码:
<html>
<head>
<title></title>
</head>
<body>
广告。。。。。。。。。
<a href="/fday11/example/DemoReferer.jsp">惊爆凤姐最新消息.................</a>
</body>
</html>
链接页面代码:
<%@ page language="java" pageEncoding="UTF-8"%>
<%@taglib uri="http://www.exfrc.org" prefix="exfrc"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" >
//使用自定义处理防盗链标签
<exfrc:DemoReferer site="http://localhost" page="index.jsp" /> <html>
<head>
<title>DemoReferer</title>
</head>
<body>
凤姐....................凤姐
</body>
</html>
标签处理DemoReferer.java页面代码
package cn.itcast.web.example;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.SkipPageException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
public class DemoReferer extends SimpleTagSupport {
private String site;
private String page;
public void setSite(String site) {
this.site = site;
}
public void setPage(String page) {
this.page = page;
}
@Override
public void doTag() throws JspException, IOException {
PageContext context=(PageContext) this.getJspContext();
HttpServletRequest request=(HttpServletRequest) context.getRequest();
HttpServletResponse response=(HttpServletResponse) context.getResponse();
String referer=request.getHeader("referer");
if(referer==null||!referer.startsWith(site)){ //必须先判null 否则可能出现空指针异常
if(page.startsWith(request.getContextPath())){
response.sendRedirect(page);
}else if(page.startsWith("/")){
response.sendRedirect(request.getContextPath()+page);
}else{
response.sendRedirect(request.getContextPath()+"/"+page);
}
throw new SkipPageException();
}
}
}
这两种方法本质上一样都是通过referer头字段进行防盗链,但是事实上这种防盗链是只能防君子而防不了小人的,也就是我们同样可以通过别的方法绕过服务器对referer的检查(如可以通过HttpURLConnection函数给链接地址发送假的referer头,从而绕过对referer的检查),所以这种防盗链防不死,天下没有不透风的墙,所以也没绝对完美的解决方案,貌似要想防死只能通过登录限制了...
表单防止重复提交
什么是表单的重复提交?
前提:在控制器中页面的跳转形式为请求转发不是请求重定向;
重复提交的表现形式:
1、在页面未转到提交页面时,多次点击提交按钮;
2、成功提交后,多次点击刷新(F5)按钮;
3、成功提交后,后退,再次点击提交按钮;
防止表单重复提交的方案:
1、在客户端防止;2、在服务器端防止;
在客户端防止之一:
在提交按钮上利用JavaScript实现,点击一次后,将onclick置为false,表单页面如下:
<head>
<title>form.html</title>
<script type="text/javascript">
var iscommitted=false;
function dosubmit(){
if(!iscommitted){
iscommitted=true;
return true;
}
else{
return false;
}
}
</script>
</head>
<body>
<form action="/fday07/servlet/formSubmitServlet1" method="post">
用户:
<input type="text" name="username">
<br />
密码:
<input type="password" name="password">
<br />
<input type="submit" value="提交" onclick="return dosubmit()">
<br />
</form>
</body>
客户端防止之二:
原理类似一都是利用JavaScript实现,但是是在提交按钮点击后将该按钮disabled属性置为disabled,表单页面代码如下:
<head> </script> <body> 通过JavaScript防止客户端重复提交还是存在一定问题的,首先,客户端浏览器可能禁用JavaScript,其次防止不了提交成功后用户点击多次刷新按钮实现的重复提交,所以保险起见,在服务器端对表单重复提交的防止是很必须的! 首先客户端程序: public class formServlet extends HttpServlet { private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest request, HttpServletResponse response) public void doPost(HttpServletRequest request, HttpServletResponse response) } class TokenProcessor { public static final TokenProcessor instance = new TokenProcessor(); public static TokenProcessor getInstance() { public String generateToken() { public class formSubmitServlet extends HttpServlet { private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest request, HttpServletResponse response) private boolean isToken(HttpServletRequest request) { public void doPost(HttpServletRequest request, HttpServletResponse response)
<title>form.html</title>
<script type="text/javascript">
function dosubmit(){
document.getElementById("submit").disabled='disabled';
return true;
}
</head>
<form action="/fday07/servlet/formSubmitServlet1" method="post">
用户:
<input type="text" name="username">
<br />
密码:
<input type="password" name="password">
<br />
<input type="submit" value="提交" onclick="return dosubmit()">
<br />
</form>
</body>
throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String token=TokenProcessor.getInstance().generateToken();
//request.setAttribute("token", token);
request.getSession().setAttribute("token", token); //服务器端的令牌
out.print("<form action='formSubmitServlet' method='post'>");
out.print("<input type='hidden' name='token' value='"+token+"'/>"); //客户端带过去的令牌
out.print("<input type='text' name='username'/>");
out.print("<input type='submit' value='提交'>");
out.print("</form>");
}
throws ServletException, IOException {
this.doGet(request, response);
}
private TokenProcessor() {
};
return instance;
}
String token = System.currentTimeMillis() + ""
+ new Random().nextInt(66666666);
MessageDigest md;
try {
md = MessageDigest.getInstance("md5");
byte md5[] = md.digest(token.getBytes());
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(md5);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
}
服务器端程序:
throws ServletException, IOException {
boolean b=isToken(request);
if(!b){
System.out.println("重复提交!!");
return ;
}
request.getSession().removeAttribute("token"); //比较完毕后服务器端移除令牌
String username=request.getParameter("username");
//out.write(username+"已经成功登录");
System.out.println(username+"用户信息已经保存到数据库");
}
String client_token=request.getParameter("token");
if(client_token==null){
return false;
}
String server_token=(String) request.getSession().getAttribute("token");
if(server_token==null){
return false;
}
if(!client_token.equals(server_token)){
return false;
}
return true;
}
throws ServletException, IOException {
this.doGet(request, response);
}
}
在服务器端防止表单重复提交的原理主要是,在客户端提交页面时生成一个唯一的token(用于唯一标识该用户)通过隐藏域带给服务器,该token为客户端client_token,同时将该token保存到request域中做为服务器端server_token,数据带到服务器端后,若为第一次提交则client_token=server_token,此时服务器端则移除保存在request域中的server_token。
如果此时用户点击刷新再次提交时,因为此时server_token==null所以再次提交也不会成功
如果用户不是通过表单提交页面链接到的该页面,那么因为server_token和client_token都为null,所以同样会阻止提交的发生。
- 网页上的一些事——拒绝“坏人”
- 提防坏人:Nginx 拒绝指定IP访问
- 提防坏人:Nginx 拒绝指定IP访问
- 提防坏人:Nginx 拒绝指定IP访问
- 提防坏人:Nginx 拒绝指定IP访问
- 提防坏人:Nginx 拒绝指定IP访问
- 在网页上的一些操作
- 心理学上说:拖延——是最厉害的拒绝
- 主机上无法访问虚拟机上的网页——解决方案
- 网页上的一些安全漏洞攻击的了解
- 网页上常用的一些在线播放器代码
- 在ipad上网页的一些优化代码
- 书单—拒绝标题党的干货
- 好人与坏人的区分之我见
- 坏人的金子不算财富吗
- 公司的三类人:白兔、坏人、新狼
- 小爬虫——下载给定网页上的图片
- 网页上使用的输入法——Google Transliteration
- 高科技留种
- Linux高级进程间通信 共享存储
- HashMap与Hashtable的区别
- 关于Windows Socket是不是一个线程的多个Socket共享消息泵
- C#中,newandOverride
- 网页上的一些事——拒绝“坏人”
- ogre框架
- (转)
- (转)
- ORACLE权限关于with admin option和with grant
- Android学习指南
- 如何设置快速的debian源
- 相邻两方格内的两个整数之和为质数-经典算法详解
- Hadoop源代码的边角料:HDFS的数据通信机制