使用Session管理用户登录状态

Updated on in Java是世界上最好的语言 with 0 views and 0 comments

  

session 是什么?

  session 是服务器与浏览器一次会话的电子凭证。
session 可以被服务器端设置时长,比如超过 1 分钟就删除本次会话中的 session,所以用 session 来做登录验证

设计思路

  比如想要访问网站里的会员资源时,那么需要登录账号以后才可以访问的,没有登录的情况下会跳转到登录页面提醒登录。

设计要点

  在 session 中存储密钥/口令,比如存储一个 code 的字符串 key,它的 value 对应的是一串字符串,后台服务器接收到一个请求是,如果这个 session 中携带 code,并且携带的 code 的值是能用的值的话,就可以放开请求访问资源,否则不能。

向 session 设值

    @GetMapping(value = "/setSession")
    public String setSession(ServletRequest req){
        HttpServletRequest request = (HttpServletRequest) req;
        HttpSession session = request.getSession();
        session.setAttribute("code","我是密码");
        return session.getId();
    }

从 session 取值

    @GetMapping(value = "/getSession")
    public String getSession(HttpSession session){
        return session.getId();
    }

使用 Filter 拦截器统一校验所有请求实现 session 拦截

@SpringBootApplication
@MapperScan("com.caining.love.mapper")
@ServletComponentScan(basePackages = "com.caining.love.config")
public class LoveApplication {

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

}
package com.caining.love.config;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@Component
public class Filter implements javax.servlet.Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpSession session = request.getSession();

        //使静态资源访问不受限制
        String url = ((HttpServletRequest) servletRequest).getRequestURL().toString();
        if(url.indexOf(".css")>0||url.indexOf(".js")>0||url.indexOf(".png")>0
                ||url.indexOf(".jpg")>0||url.indexOf(".svg")>0) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }
        //使特定接口不受限制
        if(url.indexOf("setSession")>0) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }

        //检查是否携带口令
        if(null == session || null == session.getAttribute("code")
                || StringUtils.isBlank(session.getAttribute("code").toString())){
            servletRequest.getRequestDispatcher("/register/index.html").forward(servletRequest, servletResponse);
        }else{
            filterChain.doFilter(servletRequest, servletResponse);
        }

    }

    @Override
    public void destroy() {

    }
}

SpringBoot 设置 session 过期时间

server.servlet.session.timeout=PT5M
//SpringBoot最新版使用java.time.Duration类来实现

Examples:
     "20.345 seconds"                 -- "PT20.345S
     "15 minutes" (15 * 60 seconds)   -- "PT15M"
     "10 hours" (10 * 3600 seconds)   -- "PT10H"
     "2 days" (2 * 86400 seconds)     -- "PT48H"
Note that multiples of 24 hours are not output as days to avoid confusion