request response 请求响应 + Cookie Session会话技术 + Token + MD5哈希算法

本文详细介绍了HTTP请求响应周期,重点讲解了会话技术,包括Cookie、Session和Token的区别及应用。讨论了Cookie的存储和过期时间,Session的实现方式,特别是Django中的Session存储机制。此外,还阐述了MD5哈希算法的特点和在数据完整性验证中的作用。最后提到了使用Cookie存储中文的homework任务。

请求周期

  • 客户端向服务器发送数据 Request
    • 主动操作
  • 服务端向客户端发送数据 Response
    • 响应操作
    • 没有请求,就不会有响应
  • 从Request 到 Response结束

会话技术

  • 为什么出现,有啥作用
  • 请求周期
    • request
    • response
    • Http的请求都是短连接
  • 变相延长了请求周期
    • 保存了用户的关键信息
  • 客户端会话技术

    • 数据存储在客户端的
    • Cookie
    • 数据存储 key-value
    • 支持过期
  • 服务端会话技术

  • Cookie隔离
  • 游戏浏览器
  • 过期时间

    • 关闭浏览器即失效
    • max_age 指定过期时间,默认单位是
    • None 不过期
    • 0 关闭即过期(目前不好用)

    还有一种 experis : expires=timedelta(days=14)
    - 和max_age相比,它支持时间戳,时间差

Session

  • 会话技术
  • 服务端会话技术
    • 数据存在服务器
    • Session依赖于Cookie
  • Session存储
    • Session存储在内存中
    • Django里将Session持久化到数据库中了
    • django_session表中存在三个字段
      • session_key 主键
      • session_data 数据,使用BASE64编码做了一个简单的数据安全
      • session_experis 过期时间,django中默认两周
  • Session 退出
    • 删 cookie
    • 删 session
    • 两个一起彻底删掉
  • 存储位置不一样
  • Session相对来说更安全
    • Cookie 传输明文,相对来说不安全
  • Cookie默认不支持中文
    • 编码解码
  • Session 依赖于Cookie
Token
  • 会话技术
  • 服务端会话技术
  • 自定义的Session
  • Token
    • 移动端火的时候
    • 如果Token用在Web上,建议还是使用Session
    • 如果用在专属客户端上,我们建议手动管理Token
  • Token用法
    • 直接在用户表中添加一字段,字段用来存储用户的Token值
    • 将Token存储在缓存中
用户系统
  • 用户中心
  • 用户注册
  • 用户登录
  • 用户退出
MD5
  • 信息摘要算法
    • 哈希算法
    • 杂凑算法
  • 特性
    • 单向不可逆
    • 输出长度固定
      • 128位的二进制
      • Unicode 存储的时候十六进制
      • 四位二进制转换成一个十六进制
      • 32位16进制,32位Unicode
      • 32位的字符串
    • 抗爆破能力强
    • 指纹用法验证数据完整,原数据只要发生任何变更,md5都会发生很大的变化
homework
  • 使用Cookie存储中文
  • 完成登录
<think>好的,我现在要帮用户理解如何用Spring Security和JWT做用户登录认证。首先,我得回想一下Spring Security的基本原理,以及JWT的结构和用途。用户可能是个开发者,想要整合这两个技术,但可能对具体步骤不太清楚。我需要分步骤解释,确保结构清晰。 首先,我应该从整体流程开始,比如用户登录的步骤:提交凭证,服务器验证,生成JWT,返回给客户端,后续请求携带JWT进行验证。这部分需要简明扼要,让用户有个大致的了解。 接下来可能需要详细说明每个组件的作用。比如,Spring Security的过滤器链,JWT的生成和验证工具类,以及如何将JWT集成到Spring Security中。这里要注意用户可能不熟悉过滤器,所以需要用简单的语言解释,比如JwtAuthenticationFilter的作用是拦截请求并处理Token。 然后要考虑配置部分,比如安全配置类需要扩展WebSecurityConfigurerAdapter,设置哪些端点需要认证,哪些公开。这里可能需要提到放行登录接口和Swagger等不需要认证的路径。同时,密码编码器也是必须的,比如使用BCryptPasswordEncoder。 还要处理用户认证的逻辑,UserDetailsService的实现,从数据库加载用户信息,以及自定义的认证过滤器,比如JwtAuthenticationFilter如何从请求头中提取Token,并进行验证。这里可能需要提到一旦验证成功,如何设置SecurityContextHolder。 另外,异常处理也很重要,比如认证失败时的处理,可以使用AuthenticationEntryPoint来返回401错误。可能用户会遇到Token过期或无效的情况,需要明确如何处理这些异常。 最后,测试和注意事项部分需要提醒用户在实际开发中要注意的问题,比如Token的有效期设置、HTTPS的使用、密钥的安全存储,以及刷新令牌的机制。这些是保证系统安全性的关键点。 在组织这些内容的时候,要确保每个部分都有明确的标题,比如整体流程、核心组件、配置步骤、代码示例等。代码示例部分可以用伪代码或关键代码块,帮助用户理解实现细节。同时,要避免使用过于专业的术语,或者在使用时加以解释,确保用户能够跟上思路。 可能还需要考虑用户的实际应用场景,比如是否需要在分布式系统中使用,或者如何与现有的用户数据库集成。这时候可以提到JWT的无状态特性适合分布式环境,减轻服务器端的存储压力。 最后检查是否有遗漏的步骤,比如JWT的签名算法选择(如HS256或RS256),是否需要刷新令牌机制,以及如何将用户角色权限集成到Token中,以便进行权限控制。这些细节虽然可能超出基础整合的范围,但提及它们可以帮助用户了解进一步的优化方向。 总结下来,整个思考过程需要将复杂的技术分解成易于理解的步骤,确保用户能够跟随指导完成整合,同时意识到关键的安全和实现细节。</think>### Spring Security + JWT 用户登录认证实现指南 #### 一、整体流程 1. **用户登录**:提交用户名/密码。 2. **凭证验证**:服务端验证用户身份。 3. **生成Token**:验证通过后生成JWT返回客户端。 4. **请求鉴权**:后续请求携带JWT,服务端验证有效性。 5. **资源访问**:验证通过后访问受保护资源。 #### 二、核心组件与作用 | 组件 | 职责 | |-----------------------|------------------------------------------| | `JwtUtils` | 生成/解析/验证JWT | | `JwtAuthenticationFilter` | 拦截请求,提取并验证Token | | `UserDetailsService` | 从数据库加载用户信息 | | `SecurityConfig` | 配置安全策略(开放接口、认证规则等) | #### 三、具体实现步骤 ##### 1. 添加依赖 ```xml <!-- Spring Security --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <!-- JWT支持 --> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency> ``` ##### 2. JWT工具类实现 ```java public class JwtUtils { // 密钥(需存储在安全位置) private static final String SECRET_KEY = "your-secret-key"; // 有效期(示例:2小时) private static final long EXPIRATION = 7200; // 生成Token public static String generateToken(UserDetails userDetails) { return Jwts.builder() .setSubject(userDetails.getUsername()) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION * 1000)) .signWith(SignatureAlgorithm.HS512, SECRET_KEY) .compact(); } // 解析Token public static String extractUsername(String token) { return Jwts.parser() .setSigningKey(SECRET_KEY) .parseClaimsJws(token) .getBody() .getSubject(); } } ``` ##### 3. 自定义认证过滤器 ```java public class JwtAuthenticationFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { // 1. 从Header提取Token String header = request.getHeader("Authorization"); if (header != null && header.startsWith("Bearer ")) { String token = header.substring(7); // 2. 验证Token有效性 if (JwtUtils.validateToken(token)) { String username = JwtUtils.extractUsername(token); // 3. 构建认证对象 UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username, null, new ArrayList<>()); SecurityContextHolder.getContext().setAuthentication(authentication); } } chain.doFilter(request, response); } } ``` ##### 4. 安全配置类 ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .csrf().disable() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .authorizeRequests() .antMatchers("/api/auth/login").permitAll() // 登录接口开放 .antMatchers("/swagger-ui/**").permitAll() // 示例:开放Swagger .anyRequest().authenticated() .and() .addFilterBefore(new JwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } } ``` ##### 5. 登录接口实现 ```java @RestController @RequestMapping("/api/auth") public class AuthController { @Autowired private AuthenticationManager authenticationManager; @PostMapping("/login") public ResponseEntity<?> login(@RequestBody LoginRequest request) { // 1. 执行认证 Authentication authentication = authenticationManager.authenticate( new UsernamePasswordAuthenticationToken( request.getUsername(), request.getPassword() ) ); // 2. 生成JWT UserDetails userDetails = (UserDetails) authentication.getPrincipal(); String jwt = JwtUtils.generateToken(userDetails); return ResponseEntity.ok(new JwtResponse(jwt)); } } ``` #### 四、关键安全机制 1. **无状态会**: $$ \text{SessionCreationPolicy.STATELESS} $$ 禁用Session,完全依赖Token验证 2. **Token防篡改**: 使用HMAC-SHA512签名算法: $$ \text{SignatureAlgorithm.HS512} $$ 3. **敏感信息保护**: - 密码存储使用BCrypt哈希: $$ \text{BCryptPasswordEncoder} $$ - 密钥不硬编码在代码中 #### 五、测试流程 1. 调用登录接口获取Token: ```bash curl -X POST http://localhost:8080/api/auth/login \ -H "Content-Type: application/json" \ -d '{"username":"user1", "password":"123456"}' ``` 2. 携带Token访问受保护接口: ```bash curl -H "Authorization: Bearer <your_token>" http://localhost:8080/api/protected ``` #### 六、注意事项 1. **Token有效期**:根据业务需求设置合理时间(通常1-4小时) 2. **HTTPS强制使用**:生产环境必须启用HTTPS 3. **密钥管理**:使用环境变量或配置中心存储密钥 4. **黑名单机制**:如需实现登出功能,需维护短期Token黑名单 5. **刷新令牌**:可增加refresh token机制延长会 > 通过这种实现方式,系统具备以下优势: > - 天然支持分布式架构 > - 前端可灵活存储TokenCookie/LocalStorage) > - 服务端无需维护会状态 > - 可扩展自定义Claims(如用户角色)实现细粒度权限控制
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值