当前位置: 首页 > article >正文

零碎01-登录验证

目录

一、背景故事

二、解决方案分析

1. 基于Cookie的认证

2. 基于Session的认证

3. 基于JWT的认证

三、基于JWT的Filter和Intercept实现示例

四、总结



一、背景故事

        酷乐是一名技术栈不详,遇强则强的程序员。有一天,公司开发了一个内部管理系统,初期为了便于开发测试,系统的某些接口并未加上严格的访问控制。测试人员在浏览器地址栏中直接输入系统某模块的URL,发现竟然可以不登录直接访问内容。这一漏洞很快被发现,然而其背后的登录认证校验机制的问题引发了团队的关注和重视。这一问题不仅影响系统安全,更带来潜在的数据泄露风险。

于是,酷乐开始思考如何设计一个有效的登录认证机制,以确保未经授权的访问可以被拦截。


二、解决方案分析

在登录认证校验中,主流方案包括基于Cookie、Session和JWT(JSON Web Token)三种方式。每种方案都有各自的特点与适用场景。

1. 基于Cookie的认证
  • 原理:当用户登录成功后,服务器会生成一个Cookie并存储在客户端浏览器中。后续每次请求时,浏览器会自动将该Cookie发送至服务器,服务器根据该Cookie验证用户的身份。

  • 使用方式:通常在服务器端配置Cookie的生成、加密以及过期时间,前端则无需手动处理,浏览器会自动附带Cookie。

  • 优缺点

    • 优点:实现简单,不需要客户端过多参与,适合小型系统。

    • 缺点:安全性较低,Cookie容易被窃取,且在分布式系统中服务器状态难以共享

2. 基于Session的认证
  • 原理:Session是一种将用户状态信息存储在服务器上的方式。用户登录后,服务器创建一个Session,并将Session ID通过Cookie返回给客户端。后续请求携带该Session ID,服务器可以根据此Session ID查找用户信息。

  • 使用方式:后端需要有一套Session管理机制,将Session ID与用户信息进行映射。一般来说,Session可存储在数据库或缓存中。

  • 优缺点

    • 优点:服务器可完全控制用户状态,安全性比Cookie更高

    • 缺点:对服务器存储和管理有较大开销,尤其在高并发场景下,对Session同步有较高要求

3. 基于JWT的认证
  • 原理:JWT(Json Web Token)是一种将用户信息以JSON格式加密后生成的Token。登录后,服务器生成JWT并返回给客户端,客户端在后续请求时将JWT放在HTTP头部发送给服务器,服务器通过解析JWT验证用户身份。

  • 使用方式:登录成功后生成JWT,放在HTTP Header的Authorization字段中。JWT包含有效期,过期后需要重新登录获取。

  • 优缺点

    • 优点:无状态机制,不依赖服务器存储,便于跨域和分布式环境

    • 缺点:Token一旦泄露,存在被恶意使用的风险,且JWT不支持注销,难以实时失效控制。


三、基于JWT的Filter和Intercept实现示例

在基于JWT认证的应用中,常用的方式是通过Filter或Intercept机制来拦截请求,判断JWT的合法性与有效性。

使用到的

示例代码:

  • Filter实现

// JWT Filter 实现示例
​
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 java.io.IOException;
​
public class JwtAuthenticationFilter implements Filter {
​
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化过滤器
    }
​
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String jwtToken = httpRequest.getHeader("Authorization");
​
        if (jwtToken == null || !isValidToken(jwtToken)) {
            response.getWriter().write("Unauthorized");
            return;
        }
        
        // 继续执行请求
        chain.doFilter(request, response);
    }
​
    private boolean isValidToken(String token) {
        // 验证JWT的有效性,例如检查签名和有效期
        // 这里需要现将json转为object
        return true; // 此处为示例,实际需要替换为真正的验证逻辑
    }
​
    @Override
    public void destroy() {
        // 销毁过滤器
    }
}

该过滤器会在每次请求时检查是否携带有效的JWT,无效或过期的Token将会被拦截,返回“Unauthorized”提示信息。

  • Intercept实现

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
​
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
​
@Component
public class JwtInterceptor implements HandlerInterceptor {
​
    @Autowired
    private UserDetailsService userDetailsService;
​
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("Authorization");
​
        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7); // 去掉"Bearer "前缀
​
            try {
                String username = JwtUtil.getUsernameFromToken(token);
                if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                    UserDetails userDetails = userDetailsService.loadUserByUsername(username);
​
                    if (JwtUtil.validateToken(token, userDetails)) {
                        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                                userDetails, null, userDetails.getAuthorities());
                        SecurityContextHolder.getContext().setAuthentication(authentication);
                        return true;
                    }
                }
            } catch (Exception e) {
                logger.error("Could not set user authentication in security context", e);
            }
        }
​
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        return false;
    }
​
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 可选:处理请求后的逻辑
    }
​
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 可选:处理请求完成后的逻辑
    }
}

四、总结

通过这次对登录认证校验问题的探讨,我们遵循了发现问题、查找原因、分析方案和解决问题的思路。首先,通过系统测试暴露了登录认证校验的漏洞,意识到需要更加安全的认证机制;然后在对比分析Cookie、Session和JWT等方案后,选择了更加适合分布式环境的JWT方案。最终,通过Filter和Intercept机制实现了基于JWT的认证拦截功能。


http://www.kler.cn/a/394976.html

相关文章:

  • makefile 设置动态库路径参数
  • 【HarmonyOS NEXT】一次开发多端部署(以轮播图、Tab栏、列表为例,配合栅格布局与媒体查询,进行 UI 的一多开发)
  • WordPress HTTPS 配置问题解决方案
  • 三正科技笔试题
  • 如何从头开始构建神经网络?(附教程)
  • 深入解析 OpenHarmony 构建系统-4-OHOSLoader类
  • 基于SpringBoot的“生鲜交易系统”的设计与实现(源码+数据库+文档+PPT)
  • 电脑软件:推荐一款非常好用的PDF编辑、拆分、合并、对比工具
  • C# IEnumerator,IEnumerable ,Iterator
  • python解析网页上的json数据落地到EXCEL
  • Unity3D实现视频和模型融合效果
  • springboot整合websocket实现复制目录进度推送
  • Git服务部署教程
  • C#各版本汇总
  • C#从入门到放弃
  • 计算机视觉和机器人技术中的下一个标记预测与视频扩散相结合
  • 家政服务小程序,家政行业数字化发展下的优势
  • 深度学习:利用随机数据更快地测试一个新的模型在自己数据格式很复杂的时候
  • layui的table组件中,对某一列的文字设置颜色为浅蓝怎么设置
  • anzocapital 昂首资本:外汇机器人趋势判断秘籍
  • 108. UE5 GAS RPG 实现地图名称更新和加载关卡
  • 爱普生机器人EPSON RC
  • python贪心算法实现(纸币找零举例)
  • DNS解析 附实验:DNS正反向解析
  • C++常用的特性-->day05
  • 【JavaEE进阶】Spring AOP 原理