一聚教程网:一个值得你收藏的教程网站

热门教程

springboot基于session实现登录方式

时间:2026-08-13 09:25:51 编辑:袖梨 来源:一聚教程网

springboot基于session实现登录方式并不只看表面做法,关键还要理解相关条件、限制和后续影响。

1.理解session

用户第一次在浏览器输入正确的账号密码进行http请求时候,后端会根据他的信息设置一个该账户唯一的session并保存在后端,并设置有效期,最后返回保存到浏览器cookie中。

下一次请求需要浏览器携带session到后端,校验通过,用户便可以无需登录访问,否则直接被拦截。

2.理解ThreadLocal

2.1 理解多线程

实现多线程有两种方式:(.start() 方法启动)

1.继承Thread类,在类的内部写任务执行(也就是run方法)

2.实现Runnable接口,接口内部重写run方法,在把这个实现类传递到Thread线程内部即可

总结:推荐方式2,解耦合

2.2 理解lambda表达式

注意lambda表示式必须和函数式接口结合使用

函数式接口,指的是接口中只有一个抽象方法

2.3 ThreadLocal

线程内部存放该线程对应的自己数据,线程之间相互隔离,主要用在多线程并发的场景下

3.基于session登录流程图

springboot基于session实现登录方式

1.为什么验证码是存储在session?

因为验证码是临时的,存储在session,前端请求的时候后端才能正确比对他填写的是否正确。

2.后端没有显示设置session保存到浏览器?

为什么前端请求后这个session会自动保存到浏览器的cookie里面?

用户登录成功,服务器会创建一个Session,生成唯一的JSESSIONID,JSESSIONID会通过Set-Cookie HTTP响应头返回给浏览器。

这个过程是web容器(tomcat)自动完成,无需开发者介入。

4.具体登录的代码实现

4.1短信发送功能

@Override    public Result sendCode(String phone, HttpSession session) {        // 1.校验手机号        if (RegexUtils.isPhoneInvalid(phone)){            // 2.如果不符合,返回错误信息            return Result.fail("手机号格式错误");        }        // 3.符合,生成验证码        String code = RandomUtil.randomNumbers(6);        // 4.保存验证码到session中(存储再服务器内存中)        session.setAttribute("code", code);        // 5.发送验证码        log.debug("发送短信验证码成功,验证码:{}", code);        return Result.ok();    }

4.2短信验证码登录注册功能

@Override    public Result login(LoginFormDTO loginForm, HttpSession session) {        // 1.校验手机号        String phone = loginForm.getPhone();        if (RegexUtils.isPhoneInvalid(phone)){            // 2.如果不符合,返回错误信息            return Result.fail("手机号格式错误");        }        // 2.校验验证码        String cacheCode = (String)session.getAttribute("code");        String code = loginForm.getCode();        if (cacheCode == null || !cacheCode.equals(code)){            return Result.fail("验证码不一致");        }        // 3.根据手机号码查询用户信息 select * from tb_user where phone = ? 实现了mybatisplus接口ServiceImpl<UserMapper, User>        User user = query().eq("phone", phone).one(); // query是mybatisplus的功能        // 4.判断用户是否存在        if (user == null) {            // 5.用户不存在,创建新用户并保存            user = createUserWithPhone(phone);        }        //7.保存用户信息到session中        session.setAttribute("user", BeanUtil.copyProperties(user, UserDTO.class));        return Result.ok();    }

这里可能存在一个问题,使用自己手机号接收验证码,别人手机号登录问题

5.登录校验功能

5.1配置登录拦截器LoginInterceptor

public class LoginInterceptor implements HandlerInterceptor {    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {        // 1.获取session        HttpSession session = request.getSession();        // 2.获取session中的用户        Object user = session.getAttribute("user");        // 3.判断用户是否存在        if (user == null) {            response.setStatus(401);            return false;        }        // 5.存在,保存用户信息到ThreadLocal        UserHolder.saveUser((UserDTO)user);        return true;    }    @Override    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {        // 移除用户        UserHolder.removeUser();    }}

ThrealLocal类实现

public class UserHolder {    private static final ThreadLocal<UserDTO> tl = new ThreadLocal<>();    public static void saveUser(UserDTO user) {        tl.set(user);    }    public static UserDTO getUser() {        return tl.get();    }    public static void removeUser() {        tl.remove();    }}

5.2登录拦截器加入到MvcConfig中

@Configurationpublic class MvcConfig implements WebMvcConfigurer {    @Override    public void addInterceptors(InterceptorRegistry registry) {        registry.addInterceptor(new LoginInterceptor())                .excludePathPatterns(                        "/user/code",                        "/user/login",                        "/blog/hot",                        "/shop/**",                        "/shop-type/**",                        "/upload/**",                        "/voucher/**"                );    }}

5.3 用户登录访问

    @GetMapping("/me")    public Result me(){        // 获取当前登录的用户并返回        UserDTO user = UserHolder.getUser();        return Result.ok(user);    }

总结

用户登录访问的页面需要拦截器拦截,拦截判断成功之后,才会请求访问对应的Controller。

热门栏目