ajax跨域请求SESSION不一致

一次ajax跨域请求SESSION不一致解决方案

场景重现:简单的登录注册模块,使用前后台分离,后台使用SpringMVC给前台提供数据接口支持,前台采用ajax请求后台数据。

一:验证码

package com.lemonzuo.service;

import java.io.IOException;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.lemonzuo.util.RandomVerifyImgCodeUtil;

@Controller
// 平台验证码
public class VerifyCodeService {
	
	@Autowired
	private HttpSession session;
	
	@RequestMapping(value="VerifyCodeService.do", method=RequestMethod.GET)
	public void createVerifyCode(
			HttpServletResponse response,
			@RequestParam(value="width", required=true, defaultValue="100") int width,
			@RequestParam(value="height", required=true, defaultValue="30") int height,
			@RequestParam(value="sessionName", required=true, defaultValue="verifyCode") String sessionName) {
        // 设置相应类型,告诉浏览器输出的内容为图片
		response.setContentType("image/jpeg");
		// 设置响应头信息,告诉浏览器不要缓存此内容
		response.setHeader("Pragma", "No-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setDateHeader("Expire", 0);
		
		try {
			int charSize = 4;
			String verifyCode = RandomVerifyImgCodeUtil.generateVerifyCode(charSize);
			// 将字符信息存入Session中
			session.setAttribute(sessionName, verifyCode);
	        RandomVerifyImgCodeUtil.outputImage(width, height, response.getOutputStream(), verifyCode, "login");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

二、验证码校验

	// 验证验证码的正确性
    @CrossOrigin(value="http://localhost:63342")
	@RequestMapping(value="/checkUserVerifyCode.do", 
			method=RequestMethod.POST, 
			produces="application/json;charset=UTF-8")
	@ResponseBody
	public String checkVerifyCode(
			HttpSession session,
			@RequestParam(value="verifyCode", required=true, defaultValue="") String verifyCode,
			@RequestParam(value="sessionName", required=true, defaultValue="verifyCode") String sessionName) {
		
		String sessionVerifyCode = (String) session.getAttribute(sessionName);
		verifyCode = verifyCode.toUpperCase();
		if( sessionVerifyCode != null ) {
			sessionVerifyCode = sessionVerifyCode.toUpperCase();
		}
		
		if( verifyCode.equals("") ) {
			msg.setMsgCode("3001");
			msg.setMsgInfo("信息不完整");
			msg.setMsgFlag(false);
		} else if( sessionVerifyCode != null && sessionVerifyCode.equals(verifyCode)) {
			msg.setMsgCode("3003");
			msg.setMsgInfo("验证码正确");
			msg.setMsgFlag(true);
		} else {
			msg.setMsgCode("3002");
			msg.setMsgInfo("验证码错误");
			msg.setMsgFlag(false);
		}
		return gson.toJson(msg);
	}

三、ajax请求

    /* 校验验证码 */
    $('#verifyCode').on('blur', function () {
        $verifyCode = $(this).val();
        if( $verifyCode != null ) {
            $.ajax({
                type: 'POST',
                url: 'http://127.0.0.1:8080/onlineLearn/checkUserVerifyCode.do',
                data: {
                    verifyCode: $verifyCode,
                    sessionName: 'UserRegistVerifyCode'
                },
                dataType: 'json',
                error: function (msg) {
                    showModifyMessage("服务器开小差了", "error")
                },
                success: function (msg) {
                    if( msg.msgFlag) {
                        showModifyMessage(msg.msgInfo, 'info');
                    } else {
                        showModifyMessage(msg.msgInfo, 'warning');
                    }
                }
            })
        }
    });

前台联调结果异步验证验证码的一致性验证结果为验证码不一致。

采用POSTMan验证,验证通过。

于是联想到ajax请求方式未携带jessionid,导致在浏览器端联调导致验证不通过。

解决方案如下:

前台:

    /* 校验验证码 */
    $('#verifyCode').on('blur', function () {
        $verifyCode = $(this).val();
        if( $verifyCode != null ) {
            $.ajax({
                type: 'POST',
                url: 'http://127.0.0.1:8080/onlineLearn/checkUserVerifyCode.do',
                xhrFields: {
                    withCredentials: true
                },
                data: {
                    verifyCode: $verifyCode,
                    sessionName: 'UserRegistVerifyCode'
                },
                dataType: 'json',
                error: function (msg) {
                    showModifyMessage("服务器开小差了", "error")
                },
                success: function (msg) {
                    if( msg.msgFlag) {
                        showModifyMessage(msg.msgInfo, 'info');
                    } else {
                        showModifyMessage(msg.msgInfo, 'warning');
                    }
                }
            })
        }
    });

后台:

验证码:

package com.lemonzuo.service;

import java.io.IOException;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.lemonzuo.util.RandomVerifyImgCodeUtil;

@Controller
// 平台验证码
public class VerifyCodeService {
	
	@Autowired
	private HttpSession session;
	
	@RequestMapping(value="VerifyCodeService.do", method=RequestMethod.GET)
	public void createVerifyCode(
			HttpServletResponse response,
			@RequestParam(value="width", required=true, defaultValue="100") int width,
			@RequestParam(value="height", required=true, defaultValue="30") int height,
			@RequestParam(value="sessionName", required=true, defaultValue="verifyCode") String sessionName) {
        // 设置相应类型,告诉浏览器输出的内容为图片
		response.setContentType("image/jpeg");
		// 解决跨域
		response.setHeader("Access-Control-Allow-Credentials", "true");
		// 设置响应头信息,告诉浏览器不要缓存此内容
		response.setHeader("Pragma", "No-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setDateHeader("Expire", 0);
		
		try {
			int charSize = 4;
			String verifyCode = RandomVerifyImgCodeUtil.generateVerifyCode(charSize);
			// 将字符信息存入Session中
			session.setAttribute(sessionName, verifyCode);
	        RandomVerifyImgCodeUtil.outputImage(width, height, response.getOutputStream(), verifyCode, "login");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

验证码校验:

	// 验证验证码的正确性
	@RequestMapping(value="/checkUserVerifyCode.do", 
			method=RequestMethod.POST, 
			produces="application/json;charset=UTF-8")
	@ResponseBody
	public String checkVerifyCode(
			HttpSession session,
			@RequestParam(value="verifyCode", required=true, defaultValue="") String verifyCode,
			@RequestParam(value="sessionName", required=true, defaultValue="verifyCode") String sessionName) {
		
		response.setHeader("Access-Control-Allow-Credentials", "true");
		
		String sessionVerifyCode = (String) session.getAttribute(sessionName);
		verifyCode = verifyCode.toUpperCase();
		if( sessionVerifyCode != null ) {
			sessionVerifyCode = sessionVerifyCode.toUpperCase();
		}
		
		if( verifyCode.equals("") ) {
			msg.setMsgCode("3001");
			msg.setMsgInfo("信息不完整");
			msg.setMsgFlag(false);
		} else if( sessionVerifyCode != null && sessionVerifyCode.equals(verifyCode)) {
			msg.setMsgCode("3003");
			msg.setMsgInfo("验证码正确");
			msg.setMsgFlag(true);
		} else {
			msg.setMsgCode("3002");
			msg.setMsgInfo("验证码错误");
			msg.setMsgFlag(false);
		}
		return gson.toJson(msg);
	}

前台:

    /* 校验验证码 */
    $('#verifyCode').on('blur', function () {
        $verifyCode = $(this).val();
        if( $verifyCode != null ) {
            $.ajax({
                type: 'POST',
                url: 'http://127.0.0.1:8080/onlineLearn/checkUserVerifyCode.do',
                xhrFields: {
                    withCredentials: true
                },
                data: {
                    verifyCode: $verifyCode,
                    sessionName: 'UserRegistVerifyCode'
                },
                dataType: 'json',
                error: function (msg) {
                    showModifyMessage("服务器开小差了", "error")
                },
                success: function (msg) {
                    if( msg.msgFlag) {
                        showModifyMessage(msg.msgInfo, 'info');
                    } else {
                        showModifyMessage(msg.msgInfo, 'warning');
                    }
                }
            })
        }
    });

浏览器端联调结果验证码一致性校验验证通过。

关键设置点

/* Access-Control-Allow-Origin 禁用 * */
response.setHeader("Access-Control-Allow-Origin", "具体域");
response.setHeader("Access-Control-Allow-Credentials", "true");

前台ajax请求中

/* ajax请求中加入 */
xhrFields: {
    withCredentials: true
}

猜你喜欢

转载自blog.csdn.net/m0_37774134/article/details/84472769