Spring Boot项目每次请求Session都不同的记录

背景

网站注册模块有个带图片验证码验证的环节,实现思路为:前端请求获取图片验证码的接口,接口里生成图片验证码,并保存在session;验证图片验证码时,从session中获取图片验证码与当前请求参数做比较,从而实现图片验证的过程。前端

问题

涉及两个接口:生成验证码和验证验证码。生成时,没有问题;到了验证环节,获取时,直接为null,没法完成验证。vue

方案一

推测多是session过时的问题,而后在相关代码处获取了一下sessionid,而后测试了一下,果真sessionid在两次请求时已经不同。更改了session的有效期java

package com.xxx.xxx;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }


    /**
     * session时长设置
     * @return
     */
    @Bean
    public EmbeddedServletContainerCustomizer containerCustomizer(){
        return new EmbeddedServletContainerCustomizer() {
            @Override
            public void customize(ConfigurableEmbeddedServletContainer Container) {
                Container.setSessionTimeout(12*60*60);//单位为S
            }
        };
    }
}

在Spring boot的入口函数Application,经过EmbeddedServletContainerCustomizer设置session有效期。然而,试过以后发现,依然没法解决个人问题。web

方案二

参考:https://segmentfault.com/q/1010000016003300/a-1020000016541534spring

修改后端文件WebMvcConfigurer,增长如下内容:apache

package com.xxx.xxx.configurer;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;


import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.servlet.mvc.method.annotation.ServletWebArgumentResolverAdapter;

/**
 * Spring MVC 配置
 */
@Configuration
public class WebMvcConfigurer extends WebMvcConfigurerAdapter {

    private final Logger logger = LoggerFactory.getLogger(WebMvcConfigurer.class);

    //解决跨域问题
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        System.out.println("我是MyWebConfig跨域");
        // 设置容许跨域的路径
        registry.addMapping("/**")
                // 设置容许跨域请求的域名
                .allowedOrigins("*")
                // 是否容许证书,再也不默认开启
                .allowCredentials(true)
                // 设置容许的方法
                .allowedMethods("*")
                // 跨域容许时间
                .maxAge(3600);
        /*registry.addMapping("/**");*/
    }


}

因为该方案须要前端在js或vue中设置请求,手边没有现成的前端项目,故做罢。json

方案三

请教大佬。segmentfault

因为项目架构是大佬所搭,得空请教了一下,原来是项目里对cookie设置了domain的属性:设置domain以后,每次请求都会查看一下该次请求是否带有domain里对应的内容,有的话会带上sessionid做为一次会话;没有的话不会带上sessionid天然就成了两次请求,故sessionid每次都不同。现阶段开发阶段暂时不须要为cookie设置domain,故直接将相关配置注释掉,问题解决。配置文件摘录以下:后端

application-dev.properties跨域

# 开发环境配置
##端口和前缀
server.port=8080
server.context-path=
server.session.cookie.http-only=true
server.session.cookie.path=
-- 注释掉该行以后,问题解决 --
# server.session.cookie.domain=xxx.com
server.session.cookie.name=xxx

先记录一下该次的经验,深刻的原理和更多的知识之后再慢慢体会。

相关文章
相关标签/搜索