Java架构学习(十七)Http与Https区别&HttpClient发送请求&使用Postman&防止模拟请求&Token令牌&xss攻击防御

版权声明:本文为博主原创文章,未经博主允许不得转载。如需要授权请联系[email protected] https://blog.csdn.net/leeue/article/details/81381804

表单重复提交&防止模拟请求&跨域解决方案

一、Http与Https的区别

Https与Http最大的区别:
    Https:是走ssl+证书加密传输的 缺点:效率低、安全非常高
    http:不是加密的。是不安全的,使用抓包工具可以抓到。


1、笔记本上创建一个wifi
2、手机连接wifi  可以进行对手机进行抓包分析。

post请求:浏览器看不到提交的参数,但是使用抓包工具可以抓到。

总结:https安全性比http高,https需要使用证书加密传输,效率低。

安全方面:需要加密传输。使用密码、token,使用https来传输。
https:端口443端口,http:端口是80

二、使用HttpClient发送请求

package com.leeue.httpclient;

import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

/**
 * 
 * @classDesc: 功能描述:(模拟httpClient发送请求)
 * @author:<a href="[email protected]">李月</a>
 * @Version:v1.0
 * @createTime:2018年8月3日 上午10:02:39
 */
public class HttpClientDemo {
    public static void main(String[] args) {

        get();
    }

    public static void get() {
        try {
            //1.创建默认连接
            CloseableHttpClient httpClient = HttpClients.createDefault();
            //2.创建get请求
            HttpGet httpGet = new HttpGet("https://www.baidu.com");
            //3.发送请求
            CloseableHttpResponse response = httpClient.execute(httpGet);
            //4.获取状态
            int statusCode = response.getStatusLine().getStatusCode();
            System.out.println("获取状态码code:"+statusCode);
            //5.获取返回的
            if(statusCode == 200) {
                System.out.println(EntityUtils.toString(response.getEntity()));
            }
            //6.关闭连接
            response.close();
            httpClient.close();
        } catch (Exception e) {
            // TODO: handle exception
        }
    }
}

三、长连接与短连接区别

长连接与短连接的区别
Http1.0:属于短连接
http1.1:新增了长连接,默认是长连接,保留了短连接

短连接:要建立三次握手-->数据传输-->关闭连接(四次挥手)
长连接:效率高
    要建立三次握手-->数据传输-->保持连接-->数据传输-->关闭连接(四次挥手)

web网站是长连接好还是短连接好?
长连接什么时候关闭?
答:1.配置失效心跳时间,客户端没有继续建立连接,就关闭
   2.客户端主动关闭
   3.tomcat服务器配置长连接超时时间。20分钟。



长连接与短连接场景:
长连接:默认网站都是长连接、rcp远程调用、dubbo、netty长连接、
       移动app消息推送。使用长连接推送。
短连接:调用接口如果不是特别频繁,基本都是短连接。

四、跨域5钟解决方案 跨域问题只是在ajax调用产生

什么是跨域?
跨域其实是浏览器安全机制。请求访问的域名与ajax请求地址不一致,浏览器会直接无
法返回请求结果


跨域产生原因:在当前域名请求的网站中,默认不允许通过AJAX请求发送给其他域名。

案例:
这里写图片描述

返回结果:
这里写图片描述
跨域失败,控制台报错
这里写图片描述

这就是跨域的案例
其实数据已经返回来了,只是前端不能显示而已
控制台可以看出
这里写图片描述

Ajax跨域问题?
答:ajax访问的域名与浏览器直接访问的域名不一致,就会出现跨域问题。




解决跨域的方法
1、使用后台response添加header
    后台response添加header,
    response.setHeader("Access-Control-Allow-Origin", "*"); 
    支持所有网站 因为写了 *

这里写图片描述
2、使用jsonp
前端代码:

$.ajax({
            type : "POST",
            async : false,
            url : "http://a.a.com/a/FromUserServlet?userName=张三",
            dataType : "jsonp",//数据类型为jsonp  
            jsonp : "jsonpCallback",//服务端用于接收callback调用的function名的参数  
            success : function(data) {
                alert(data.result);
            },
            error : function() {
                alert('fail');
            }
        });
跨域五中解决方案
1、使用后台response添加header
2、使用jsonp
3、后台http进行转发
4、使用接口网关  -nginx进行转发
5、使用springcloud网关

jsonp原理

使用script回掉,发送get请求。script标签是可以进行跨域的。
回掉的时候传入的参数回带回来。

如图:
这里写图片描述

使用httpclient转发

使用httpclient转发
缺点:浪费资源,根本不存在跨域问题。
优点:就是安全,抓包分析不到

五、怎么防止模拟请求 使用token解决

表单重复提交场景:网络延迟、刷新、点击后退 --解决办法就是使用token
如何防止模拟请求。


如何防止模拟Http请求?
分场景解决:
1、前端解决
    1、提交按钮点击之后。按钮变灰
    2、通过标识来解决。

2、后端解决
    使用token解决。


    什么是Token?
        就是令牌的意思,有有效期限、唯一不重复的标识。
    token累死与session中的sessionID

案例代码

package com.leeue.form;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;

/**
 * 
 * @classDesc: 功能描述:(防止表单提交案例 使用token解决方案)
 * @author:<a href="[email protected]">李月</a>
 * @Version:v1.0
 * @createTime:2018年8月3日 下午1:25:39
 */
@WebServlet("/doform")
public class DoFormServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        if(isFlag(req,resp)) {
            req.setCharacterEncoding("UTF-8");
            String userName = req.getParameter("userName");
            try {
                Thread.sleep(300);
            } catch (Exception e) {
                // TODO: handle exception
            }
            System.out.println("往数据库插入数据...." + userName);
            resp.getWriter().write("success");
            // 比对后一次就需要移除
            req.getSession().removeAttribute("sessionToken");

        }

    }

    public boolean isFlag(HttpServletRequest req,HttpServletResponse resp) throws IOException {

        String token = req.getParameter("sessionToken");
        if (StringUtils.isEmpty(token)) {
            System.out.println("token is null");
            resp.getWriter().println("token is null");
            return false;
        }

        // 从session里面获取session进行比对。
        String sessionToken = (String) req.getSession().getAttribute("sessionToken");
        if (StringUtils.isEmpty(sessionToken)) {
            System.out.println("重复提交token");
            resp.getWriter().println("no repeat submit");
            return false;
        }
        if(!token.equals(sessionToken)) {
            System.out.println("伪造token ");
            resp.getWriter().println("forge token");
            return false;
        }
        if(token.equals(sessionToken)) {    
            return true;
        }

        return false;

    }

}

使用token的时候是存放redies中的

六、xss攻击与防御

什么是xss攻击?
答:就是通过JavaScript脚本注入进行攻击。

如何防御xss攻击?
注意只能使用火狐浏览器进行演示,谷歌浏览器已经自动屏蔽掉了xss攻击。



解决方案:步骤
    1、使用过滤器拦截所有请求。
    2、重写获取值的方法,将特殊字符转换程html


定义拦截所有请求的过滤器
package com.leeue.servlet.demo.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 
 * @classDesc: 功能描述:(定义一个防御xss的过滤器 拦截所有请求。)
 * @author:<a href="[email protected]">李月</a>
 * @Version:v1.0
 * @createTime:2018年8月6日 上午10:37:29
 */
public class XSSFilter implements Filter {

    public void init(FilterConfig filterConfig) throws ServletException {

    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("doFilter....");
        // 1、将ServletRequest转换成
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        // 2、重写request
        XssAndSqlHttpServletRequestWrapper xssRequestWrapper = new XssAndSqlHttpServletRequestWrapper(req);
        // 3.传入的对象是重写的request对象
        chain.doFilter(xssRequestWrapper, response);

    }

    public void destroy() {

    }

}
重写request方法
package com.leeue.servlet.demo.filter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;

public class XssAndSqlHttpServletRequestWrapper extends HttpServletRequestWrapper  {
    private HttpServletRequest request;
    public XssAndSqlHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
        this.request = request;
    }

    /**
     * 重写getParameter
     */
    @Override
    public String getParameter(String name) {
        String value = request.getParameter(name);
        System.out.println("没有转换之前..."+value);
        if(!StringUtils.isEmpty(value)) {
            //将特殊字符转换成HTML
            value = StringEscapeUtils.escapeHtml4(value);
        }
        return value;
    }


}

猜你喜欢

转载自blog.csdn.net/leeue/article/details/81381804