一 图片防盗链
图片放盗链,就是说你上传到服务器端的网站的图片,被别人调用了,以至于你的图片的链接别人只要放在别人的网站上,也一样可以通过你的网站的地址在别人的网站上展示这张图片,那么怎么才能够防止你的图片不被其他人盗用呢。我们可以定义一个拦截器,进行请求路径于域名的检测。
1.1 配置过滤器
<filter>
<filter-name>ImgFilter</filter-name>
<filter-class>com.itmayiedu.filter.ImgFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ImgFilter</filter-name>
<url-pattern>/static/*</url-pattern>
</filter-mapping>
1.2 拦截器代码
public class ImgFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("初始化...");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("doFilter....");
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
//获取请求头中来源
String referer = req.getHeader("referer");
//获取当前请求名称
String serverName = request.getServerName();
System.out.println("referer:"+referer+"----serverName:"+serverName+":"+serverName);
if(referer==null||(!referer.contains(serverName))){
req.getRequestDispatcher("/imgs/error.png").forward(req, res);
return ;
}
chain.doFilter(req, res);
}
public void destroy() {
}
如上所示获取请求头中的referer是否是源于同一个域来作为图片防盗链。
二 表单重复提交
1.1 原理
表单重复提交,就是在提交表单的时候多次点击,看似提交了一次,实际已经做了多次提交的累加,还有就是提交以后,再次刷新页面的时候,又会产生一次提交,诸如此类的问题都属于表单重复提交的问题,没有解决请求的密等性问题。
如上图所示要解决这个表单重复提交问题我可以,把之前从页面到表单页面的请求方式转换一下变成先从后台再到页面。这个时候后台生成一个token值。作为表单的影藏域,提交表单的时候,我们可以把token值也提交过去,可以通过对token值进行校验。如果两个token值相等的话,删除后台缓存中的token。不相等的就可以判断已经不是第一次进行提交了。
具体做法如下
1.2 案例
后台
@WebServlet("/ForwardServlet")
public class ForwardServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getSession().setAttribute("sesionToken", TokenUtils.getToken());
req.getRequestDispatcher("form.jsp").forward(req, resp);
}
}
前台页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Form表单</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/DoFormServlet"
method="post" onsubmit="return dosubmit()">
<input type="hidden" name="token" value="${sesionToken}"> 用户名:<input type="text"
name="userName"> <input type="submit" value="提交" id="submit">
</form>
</body>
</html>
表单校验
@WebServlet("/DoFormServlet")
public class DoFormServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
boolean flag = isFlag(req);
if (!flag) {
resp.getWriter().write("已经提交...");
System.out.println("数据已经提交了..");
return;
}
String userName = req.getParameter("userName");
try {
Thread.sleep(300);
} catch (Exception e) {
// TODO: handle exception
}
System.out.println("往数据库插入数据...." + userName);
resp.getWriter().write("success");
}
public boolean isFlag(HttpServletRequest request) {
HttpSession session = request.getSession();
String sesionToken = (String) session.getAttribute("sesionToken");
String token = request.getParameter("token");
if (!(token.equals(sesionToken))) {
return false;
}
session.removeAttribute("sesionToken");
return true;
}
}
三 模拟请求
也就是请求伪造,通过构造请求来疯狂的请求网站,这个问题。也可以通过。表单重复提交的方式,来防止疯狂的同源IP的攻击。只要是同一个IP它每请求一次都会冲后台生成一个token它都要做一次切换。这样就有效的避免了模拟请求。所有的内部暴露接口。为了防止用户不断的请求都可以通过
https://cx.com?sign=xxx&code=md5(xxx);
可以使用类似md5的自己构建的算法,通过随机生成的参数sign进行随机校验。这样就可以保证内部暴露接口不被外部疯狂的请求。至于向外暴露的接口,每一个源IP若非特殊设计,可以限制它在一定时间的的请求次数。选择拒绝。
四 跨域
1 通过jsonp,只能解决get跨域问题
2 通过httpclient进行内部转发
3 通过nginx代理服务器,转向正确的玉面
4 通过springcloud相关知识的zuul网关机制进行处理