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

网站后台慢wordpress编辑器不能用

网站后台慢,wordpress编辑器不能用,网络营销是什么的必然产物,天津网站建设培训目录 前言阅读对象阅读导航前置知识笔记正文一、Spring Security介绍1.1 什么是Spring Security1.2 它是干什么的1.3 Spring Security和Shiro比较 二、快速开始2.1 用户认证2.1.1 设置用户名2.1.1.1 基于application.yml配置文件2.1.1.2 基于Java Config配置方式 2.1.2 设置加密… 目录 前言阅读对象阅读导航前置知识笔记正文一、Spring Security介绍1.1 什么是Spring Security1.2 它是干什么的1.3 Spring Security和Shiro比较 二、快速开始2.1 用户认证2.1.1 设置用户名2.1.1.1 基于application.yml配置文件2.1.1.2 基于Java Config配置方式 2.1.2 设置加密方式2.1.2.1 {id}encodedPassword2.1.2.2 使用PasswordEncoder加密 2.1.3 自定义用户信息加载2.1.4 自定义登录页面2.1.5 前后端分离认证2.1.6 用户认证流程总结 2.2 访问控制2.2.1 web授权 基于url的访问控制2.2.2 方法授权基于注解的访问控制 三、Spring Security整合JWT实现自定义登录认证3.1 自定义登录认证业务流程3.2 JWT介绍3.2.1 什么是JWT 3.3 JWT结构3.3.1 JWT头部header3.3.2 JWT载荷payload3.3.3 JWT签名signature3.3.4 组合在一起3.3.5 如何使用 3.4 代码实现自定义登录3.5 JWT续期问题3.5.1 刷新令牌Refresh Token3.5.2 自动延长JWT有效期 学习总结感谢 前言 阅读对象 阅读导航 系列上一篇文章《》 前置知识 笔记正文 一、Spring Security介绍 1.1 什么是Spring Security 官方介绍Spring Security 是一个功能强大且高度可定制的身份验证和访问控制框架。它是用于保护基于 Spring 的应用程序。 Spring Security 是一个框架侧重于为 Java 应用程序提供身份验证和授权。与所有 Spring 项目一样Spring 安全性的真正强大之处在于它很容易扩展以满足定制需求 Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean充分利用了Spring IoC、DI和AOP功能类别是安全服务体系。 Spring Security对Web安全性的支持大量地依赖于Servlet过滤器。它可以提供应用程序层的安全解决方案一个系统的安全还需要考虑传输层和系统层的安全例如采用Htps协议、服务器部署防火墙等。 此外Spring Security采用【安全层】的概念使每一层都尽可能安全连续的安全层可以达到全面的防护。在Controller层、Service层、DAO层等以加注解的方式来保护应用程序的安全。 1.2 它是干什么的 Spring Security 主要干的就两件事 Authentication认证who are you。用户认证就是判断一个用户的身份是否合法的过程用户去访问系统资源时系统要求验证用户的身份信息身份合法方可继续访问不合法则拒绝访问。常见的用户身份认证方式有用户名密码登录二维码登录手机短信登录指纹认证等方式Access Control访问控制what are you allowed to do。授权是用户认证通过后根据用户的权限来控制用户访问资源的过程拥有资源的访问权限则正常访问没有权限则拒绝访问 SpringSecurity在架构上将认证与授权分离并提供了扩展点。 1.3 Spring Security和Shiro比较 在 Java 生态中目前有 Spring Security 和 Apache Shiro 两个安全框架可以完成认证和授权的功能。 Shiro一个功能强大且易于使用的Java安全框架提供了认证、授权、加密和会话管理 相同点不同点以SpringSecurity出发SpringSecutiry认证功能授权功能加密功能会话管理缓存支持rememberMe功能优点1. SpringSecurity以Spring为基础与Spring生态融合有天然的优势2. SpringSecurity功能更加丰富些例如安全防护3. SpringSecurity社区资源比Shiro丰富缺点1. SpringSecurity使用相对复杂上手难度大2. SpringSecurity依赖于Spring容器Shiro 所以网上有人说对于常见的安全管理技术栈的组合是 SSM ShiroSpring Boot/Spring Cloud Spring Security 二、快速开始 接下来我们开始使用以下SpringSecutiry在项目要开始之前我们需要做一些项目准备。 1快速新建一个SpringBoot项目 建议直接使用idea的Spring Initializer云上构建一个 2添加pom依赖 !-- 接入spring security--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-security/artifactId/dependency!-- web配置--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency3添加测试接口 GetMapping(/user/admin)public User admin() {User user new User();user.setUserId(1);user.setName(admin);user.setPhone(10086);return user;}4启动项目开始测试 引入Spring Security之后 访问任何API 接口时需要首先进行登录才能进行访问。如下所示 默认用户名user密码可以查看控制台日志获取 输入账号密码之后访问就正常了 5退出 Spring security默认实现了logout退出用户只需要向 Spring Security 项目中发送/logout请求即可 OK准备工作做完之后接下来开始进入正题。 2.1 用户认证 2.1.1 设置用户名 2.1.1.1 基于application.yml配置文件 配置内容如下 spring:# Spring Security 配置项对应 SecurityProperties 配置类security:user:name: userpassword: 123456roles:- admin这个方式很容易理解毕竟我们在前面提到过了SpringSecurity会有一个默认的用户。然而我们又没有在数据库里面记录它所以它肯定是存在于内存中。所以SpringSecurity提供了这么一种机制给我们去修改它的默认账号密码。 2.1.1.2 基于Java Config配置方式 代码如下 Configuration EnableWebSecurity public class SecurityConfig {Beanpublic UserDetailsService userDetailsService() {UserDetails user User.builder().username(shen).password({noop}123456).roles(user).build();UserDetails admin User.builder().username(admin).password({noop}123456).roles(admin, user).build();return new InMemoryUserDetailsManager(user, admin);} } 注意上面的密码password({noop}123456)中的{noop}是表示不需要加密明文注册到内存中。至于加密我会在后面提到。若没有上面这个配置测试的时候会报错There is no PasswordEncoder mapped for the id null 2.1.2 设置加密方式 2.1.2.1 {id}encodedPassword 这种方式是SpringSecurity提供的一种比较普适性的格式。整体分为两个部分 {id}设置的时候必须在{}花括号内。id为加密方式。可选的值如下图所示。大家只要记得{noop}是明文方式就好其他代表的是不同的加密策略 具体见org.springframework.security.crypto.factory.PasswordEncoderFactories encodePassword原始密码 简单的使用示例就是我在上个案例写到的不过在这里我们修改一下shen用户的密码采用{sha256}加密方式明文为password public class SecurityConfig {Beanpublic UserDetailsService userDetailsService() {UserDetails user User.builder().username(shen).password({sha256}97cde38028ad898ebc02e690819fa220e88c62e0699403e94fff291cfffaf8410849f27605abcbc0).roles(user).build();UserDetails admin User.builder().username(admin).password({noop}123456).roles(admin, user).build();return new InMemoryUserDetailsManager(user, admin);} }2.1.2.2 使用PasswordEncoder加密 这个使用起来就更简单了就是先注册声明一个Bean到Spring里面就好比如使用bcrypt通过上图PasswordEncoderFactories可以看见需要注册的Bean如下 Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}2.1.3 自定义用户信息加载 在我们的开发中通常是需要自定义的方式从数据库获取用户信息的。这种情况下我们可以自行实现UserDetailsService接口 Service public class ShenUserService implements UserDetailsService {Resourceprivate UserService userService;Resourceprivate PasswordEncoder passwordEncoder;Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {User byId userService.getOne(new LambdaQueryWrapperUser().eq(User::getName, username));return org.springframework.security.core.userdetails.User.builder().username(byId.getName()).password(passwordEncoder.encode(123456)).roles(user).build();} }2.1.4 自定义登录页面 Spring Security虽然给我们提供了默认登录页面但通常我们都会自定义自己的登录页面在项目中我们想要自定义登录页面只需要简单的两步 1编写登录页面 在resources目录下新建static目录然后在下面新增login.html文件内容如下 !DOCTYPE html html langen headmeta charsetUTF-8titleTitle/title /head bodyform action/user/login methodpost用户名:input typetext nameusername/br/密码input typepassword namepassword/br/input typesubmit value提交//form /body /html2配置Spring Security的过滤器链SecurityFilterChain Beanpublic SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests((authorizeHttpRequests) - authorizeHttpRequests.requestMatchers(new RequestMatcher() {Overridepublic boolean matches(HttpServletRequest request) {String requestURI request.getRequestURI();return /login.html.equals(requestURI);}}).permitAll() // loginPage 页面不需要身份认证 否则会无限重定向.anyRequest().authenticated() // 其他请求都需要用户认证后访问).formLogin((formLogin) - formLogin.loginPage(/login.html) // 自定义登录页面路径.usernameParameter(username) // 定义从Form中获取用户名的key 与html中的form参数匹配.passwordParameter(password) // 定义从Form中获取密码的key 与html中的form参数匹配.loginProcessingUrl(/user/login) // 认证发起的URL访问该URL则认证凭证 这样要与HTML中form的提交地址一致.defaultSuccessUrl(/user/admin) // 认证成功之后跳转的路径)// 禁用httpBasic.httpBasic((httpBasic) - httpBasic.disable())// 关闭跨站点请求伪造csrf防护.csrf((csrf) - csrf.disable());return http.build();}测试一下你就会发现跳转到了自定义的界面 2.1.5 前后端分离认证 表单登录配置模块提供了successHandler和failureHandler两个方法分别处理登录成功和登录失败的逻辑。携带当前登录用户名及其角色等信息而failureHandler()方法携带一个AuthenticationException异常参数。 1新增登录成功处理 /*** 认证成功处理逻辑*/public class LoginSuccessHandler implements AuthenticationSuccessHandler {Overridepublic void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {response.setContentType(text/html;charsetutf-8);response.getWriter().write(登录成功);}}2新增登录失败处理 /*** 认证失败处理逻辑*/public class LoginFailureHandler implements AuthenticationFailureHandler {Overridepublic void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {// TODOresponse.setContentType(text/html;charsetutf-8);response.getWriter().write(登录失败);exception.printStackTrace();}}3设置处理逻辑 修改上一步提到的过滤器链SecurityFilterChain代码如下 .formLogin((formLogin) - formLogin.loginPage(/login.html) // 自定义登录页面路径.usernameParameter(username) // 定义从Form中获取用户名的key 与html中的form参数匹配.passwordParameter(password) // 定义从Form中获取密码的key 与html中的form参数匹配.loginProcessingUrl(/user/login) // 认证发起的URL访问该URL则认证凭证 这样要与HTML中form的提交地址一致.defaultSuccessUrl(/user/admin) // 认证成功之后跳转的路径.successHandler(new LoginSuccessHandler()) // 登录成功处理逻辑.failureHandler(new LoginFailureHandler()) // 登录失败处理逻辑2.1.6 用户认证流程总结 网上找的一个流程图我跟着走了一遍大概是这样的只不过有些类需要自己走一下确定一下 2.2 访问控制 授权的方式包括 web授权和方法授权web授权是通过url拦截进行授权方法授权是通过方法拦截进行授权。 2.2.1 web授权 基于url的访问控制 Spring Security可以通过http.authorizeRequests()对web请求进行授权保护 Spring Security使用标准Filter建立了对web请求的拦截最终实现对资源的授权访问。配置顺序会影响之后授权的效果越是具体的应该放在前面越是笼统的应该放到后面。 代码示例如下 Beanpublic SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {// 其余配置http.formLogin((formLogin) - formLogin.loginPage(/login.html) // 自定义登录页面路径.usernameParameter(username) // 定义从Form中获取用户名的key 与html中的form参数匹配.passwordParameter(password) // 定义从Form中获取密码的key 与html中的form参数匹配.loginProcessingUrl(/user/login) // 认证发起的URL访问该URL则认证凭证 这样要与HTML中form的提交地址一致.defaultSuccessUrl(/user/admin) // 认证成功之后跳转的路径.successHandler(new LoginSuccessHandler()) // 登录成功处理逻辑.failureHandler(new LoginFailureHandler()) // 登录失败处理逻辑)// 禁用httpBasic.httpBasic(AbstractHttpConfigurer::disable)// 关闭跨站点请求伪造csrf防护.csrf(AbstractHttpConfigurer::disable);// 对请求进行访问控制doSetAccessControl(http);return http.build();}private void doSetAccessControl(HttpSecurity http) throws Exception {// 设置可以直接访问的资源http.authorizeHttpRequests((permitAll) - permitAll.antMatchers(ignoreUrls).permitAll());// 设置admin特有资源只有admin可以访问http.authorizeHttpRequests((adminApi) - adminApi.antMatchers(/sys/**).hasRole(admin));// 设置wallet接口访问权限http.authorizeHttpRequests((walletApi) - walletApi.antMatchers(/wallet/**).hasAuthority(wallet:api));// 其他请求都需要用户认证后访问http.authorizeHttpRequests((others) - others.anyRequest().authenticated());}为了方便测试我写了一个简单的Controller然后新增了一些限制API RestController public class TestController {GetMapping(/test/get)public String test() {return 获取一个test资源;}GetMapping(/sys/get)public String sysTest() {return 获取一个sys资源;}GetMapping(/order/get)public String orderTest() {return 获取一个order资源;} }并且固定我的登录用户只有user:api的权限 **/ Service public class ShenUserService implements UserDetailsService {Resourceprivate UserService userService;Resourceprivate PasswordEncoder passwordEncoder;Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {User byId userService.getOne(new LambdaQueryWrapperUser().eq(User::getName, username));return org.springframework.security.core.userdetails.User.builder().username(byId.getName()).password(passwordEncoder.encode(123456)).authorities(user:api).build();} } 2.2.2 方法授权基于注解的访问控制 Spring Security在方法的权限控制上支持三种类型的注解JSR-250注解、Secured注解和支持表达式的注解。这三种注解默认都是没有启用的需要通过EnableGlobalMethodSecurity来进行启用。 另外Spring Security中定义了四个支持使用表达式的注解分别是PreAuthorize、PostAuthorize、PreFilter和PostFilter。其中前两者可以用来在方法调用前或者调用后进行权限检查后两者可以用来对集合类型的参数或者返回值进行过滤。 示例代码如下 /*** author zhangshen* date 2023/12/29 17:16* slogan 编码即学习注释断语义**/ RestController public class TestController {PreAuthorize(hasRole(ROLE_order))GetMapping(/test/get)public String test() {return 获取一个test资源;}Secured(ROLE_admin)GetMapping(/sys/get)public String sysTest() {return 获取一个sys资源;}Secured(ROLE_order)GetMapping(/order/get)public String orderTest() {return 获取一个order资源;} }三、Spring Security整合JWT实现自定义登录认证 3.1 自定义登录认证业务流程 一个简单易用的登录认证授权可以使用Spring Security JWT实现。在这个框架下认证授权流程通常如下 用户调用登录接口获取token服务端收到登录请求校验账号密码校验通过服务端使用JWT生成token并返回给用户往后前端每次请求都带上token在请求头上添加Authorization: Bearer Token服务端每次收到请求都校验token的合法性校验通过进行业务逻辑返回业务结果 大概的UML活动图如下 3.2 JWT介绍 官方传送门《JWT介绍》 3.2.1 什么是JWT JWT即JSON Web Token它是一个开放的行业标准RFC 7519它定义了一种简介的、自包含的【协议格式】用于在通信双方【传递json对象】传递的信息经过数字签名可以被验证和信任。JWT可以使用HMAC算法或使用RSA的公钥/私钥对来签名防止被篡改。 关键词【协议格式】、【JSON对象】 它具有如下优点 JWT令牌的优点 jwt基于json非常方便解析可以在令牌中自定义丰富的内容易扩展通过非对称加密算法及数字签名技术JWT防止篡改安全性高源服务使用JWT可不依赖授权服务即可完成授权 缺点 JWT令牌较长占存储空间比较大。安全性取决于密钥管理。JWT 的安全性取决于密钥的管理。如果密钥被泄露或者被不当管理那么 JWT 将会受到攻击。因此在使用 JWT 时一定要注意密钥的管理包括生成、存储、更新、分发等等无法撤销。由于 JWT 是无状态的一旦 JWT 被签发就无法撤销。如果用户在使用 JWT 认证期间被注销或禁用那么服务端就无法阻止该用户继续使用之前签发的 JWT。因此开发人员需要设计额外的机制来撤销 JWT例如使用黑名单或者设置短期有效期等等。 使用 JWT 主要用来做下面两点 认证(Authorization)这是使用 JWT 最常见的一种情况一旦用户登录后面每个请求都会包含 JWT从而允许用户访问该令牌所允许的路由、服务和资源。单点登录是当今广泛使用 JWT 的一项功能因为它的开销很小。信息交换(Information Exchange)JWT 是能够安全传输信息的一种方式。通过使用公钥/私钥对 JWT 进行签名认证。此外由于签名是使用 head 和 payload 计算的因此你还可以验证内容是否遭到篡改。 3.3 JWT结构 一个JWT实际上就是一个由.分隔成三部分的字符串有点拗口。这三部分其实就是头部header、载荷payload与签名signature。 简洁形式的JWT字符串格式就像这样xxxxxx.yyyyyy.zzzzzz。具体如下图所示 3.3.1 JWT头部header 头部用于描述关于该JWT的最基本的信息通常包含两部分 类型在这里即JWT签名所用的算法如HMACSHA256或RSA等。 例如 {alg: HS256,typ: JWT }然后将头部进行base64加密该加密是可以对称解密的)构成了第一部分 eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ93.3.2 JWT载荷payload 第二部分是载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品这些有效信息包含三个部分 标准中注册的声明。这些是一组预定义的声明它们不是强制性的但推荐使用以提供一组有用的、可互操作的声明。其中包括:iss(发行者)、exp(过期时间)、sub(主题)、aud(受众)等公共的声明。公共的声明可以添加任何的信息一般添加用户的相关信息或其他业务需要的必要信息但不建议添加敏感信息因为该部分在客户端可解密私有的声明。私有声明是提供者和消费者所共同定义的声明一般不建议存放敏感信息因为base64是对称解密的意味着该部分信息可以归类为明文信息 一个简单的示例 {sub: 1234567890,name: John Doe,admin: true }然后将其进行base64加密得到JWT的第二部分 ewogICJzdWIiOiAiMTIzNDU2Nzg5MCIsCiAgIm5hbWUiOiAiSm9obiBEb2UiLAogICJhZG1pbiI6IHRydWUKfQ3.3.3 JWT签名signature JWT的第三部分是一个签证信息这个签证信息由三部分组成 header (base64后的)payload (base64后的)secret(盐一定要保密 这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串然后通过header中声明的加密方式进行加盐secret组合加密然后就构成了JWT的第三部分 // base64Header base64Payload String encodedString base64UrlEncode(header) . base64UrlEncode(payload);// 以zhangshen作【盐】值对上面的字符串做HS256加密 String signature HMACSHA256(encodedString, zhangshen); // khA7TNYc7_0iELcDyTc7gHBZ_xfIcgbfpzUNWwQtzME3.3.4 组合在一起 将上面三部生成的三部分组成在一起就构成了一个完整的JWT了 eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.ewogICJzdWIiOiAiMTIzNDU2Nzg5MCIsCiAgIm5hbWUiOiAiSm9obiBEb2UiLAogICJhZG1pbiI6IHRydWUKfQ.80398fd80672f162495e294c86debfaa9fac06788aa49810c7883451311d9b6d注意secret是保存在服务器端的jwt的签发生成也是在服务器端的secret就是用来进行jwt的签发和jwt的验证所以它就是你服务端的私钥在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。 3.3.5 如何使用 一般是在请求头里加入Authorization并加上Bearer标注 fetch(api/user/1, {headers: {Authorization: Bearer token} })3.4 代码实现自定义登录 现在我们来改造实现一下自定义的JWT登录。需要以下4步 步骤一新增JWT工具类 package com.shen.jwt;import cn.hutool.core.date.DateUtil; import cn.hutool.json.JSONObject; import cn.hutool.jwt.JWT; import cn.hutool.jwt.signers.JWTSignerUtil;import java.util.Map;/*** author zhanghuitong* date 2024/1/1 18:13* slogan 编码即学习注释断语义**/ public class JwtUtil {private static final String SALT zhangshen;public static final Integer EXPIRE 30;/*** 获取默认过期时间的jwt签名器*/public static JWT getJwt() {return getJwt(EXPIRE);}/*** 获取自定义过期时间的jwt签名器*/public static JWT getJwt(Integer expire) {return getJWT().setExpiresAt(DateUtil.offsetMinute(DateUtil.date(), expire));}/*** 生成jwt签名器** return*/private static JWT getJWT() {return JWT.create().setSigner(JWTSignerUtil.hs256(SALT.getBytes()));}/*** 根据token生成jwt** param token* return*/public static JWT parse(String token) {return getJWT().parse(token);}/*** 解析token*/public static JSONObject parseToken(String token) {return parse(token).getPayloads();}/*** 生成token** param claims payload声明*/public static String token(MapString, Object claims) {return getJwt().addPayloads(claims).sign();} } 上面比较重要的方法是生成JWT以及token的方法 2实现校验JWT token的过滤器 package com.shen.jwt;import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter;import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Date;/*** author zhanghuitong* date 2024/1/1 17:58* slogan 编码即学习注释断语义**/ Component public class JwtAuthticationTokenFilter extends OncePerRequestFilter {Autowiredprivate UserDetailsService userDetailsService;Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {// 1. 从请求头获取tokenString token request.getHeader(HttpHeaders.AUTHORIZATION);if (StrUtil.isEmpty(token)) {filterChain.doFilter(request, response);return;}// 2. 校验tokenString realToken token.substring(bearer.length());JSONObject tokenObject JwtUtil.parseToken(realToken);Date expireIn tokenObject.getDate(expireIn);if (expireIn.before(new Date())) {// token 已经过期SecurityContextHolder.getContext().setAuthentication(null);filterChain.doFilter(request, response);return;}String username tokenObject.getStr(username);Authentication authentication1 SecurityContextHolder.getContext().getAuthentication();if (StrUtil.isNotEmpty(username) authentication1 null) {// 获取用户信息UserDetails userDetails userDetailsService.loadUserByUsername(username);if (userDetails ! null userDetails.isEnabled()) {UsernamePasswordAuthenticationToken authentication new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));// 设置用户登录状态SecurityContextHolder.getContext().setAuthentication(authentication);}}filterChain.doFilter(request, response);} } 3添加自定义JWT过滤器并添加到账号密码校验过滤器之前 // 添加JWT过滤器登录的时候校验tokenJwtAuthticationTokenFilter jwtAuthticationTokenFilter SpringUtil.getBean(JwtAuthticationTokenFilter.class);http.addFilterBefore(jwtAuthticationTokenFilter, UsernamePasswordAuthenticationFilter.class);4最后我们来测试一下 3.5 JWT续期问题 JWTJSON Web Token通常是在用户登录后签发的用于验证用户身份和授权。JWT 的有效期限或称“过期时间”通常是一段时间例如1小时过期后用户需要重新登录以获取新的JWT。然而在某些情况下用户可能会在JWT到期之前使用应用程序这可能会导致应用程序不可用或需要用户重新登录。为了避免这种情况通常有两种解决方案来处理JWT续期问题 3.5.1 刷新令牌Refresh Token 刷新令牌是一种机制它允许应用程序获取一个新的JWT而无需用户进行身份验证。当JWT过期时应用程序使用刷新令牌向身份验证服务器请求一个新的JWT而无需提示用户输入其凭据。这样用户可以继续使用应用程序而不必重新登录。 以下是一个Java伪代码演示如何使用Refresh Token来更新JWT public String refreshAccessToken(String refreshToken) {// 刷新token校验。检查签名过期时间等boolean isValid validateRefreshToken(refreshToken);if (isValid) {// 检索与刷新令牌关联的用户信息(例如用户ID)String userId getUserIdFromRefreshToken(refreshToken);// 重新生成一个新的tokenString newToken generateToken(userId);return newAccessToken;} else {throw new RuntimeException(Invalid refresh token.);} }在这个示例中refreshAccessToken方法接收一个刷新令牌作为参数并使用validateRefreshToken方法验证该令牌是否有效。如果令牌有效方法将使用getUserIdFromRefreshToken方法获取与令牌关联的用户信息然后使用generateToken方法生成一个新的JWT访问令牌并将其返回。如果令牌无效则抛出异常。 3.5.2 自动延长JWT有效期 在某些情况下JWT可以自动延长其有效期。例如当用户在JWT过期前继续使用应用程序时应用重新设置token过期时间。 要自动延长JWT有效期您可以在每次请求时检查JWT的过期时间并在必要时更新JWT的过期时间。以下是一个示例Java代码演示如何自动延长JWT有效期 public String getAccessToken(HttpServletRequest request) {String accessToken extractAccessTokenFromRequest(request);if (isAccessTokenExpired(accessToken)) {String userId extractUserIdFromAccessToken(accessToken);accessToken generateNewAccessToken(userId);} else if (shouldRefreshAccessToken(accessToken)) {String userId extractUserIdFromAccessToken(accessToken);accessToken generateNewAccessToken(userId);}return accessToken; }private boolean isAccessTokenExpired(String accessToken) {// extract expiration time from the access tokenDate expirationTime extractExpirationTimeFromAccessToken(accessToken);// check if the expiration time is in the pastreturn expirationTime.before(new Date()); }private boolean shouldRefreshAccessToken(String accessToken) {// extract expiration time and current timeDate expirationTime extractExpirationTimeFromAccessToken(accessToken);Date currentTime new Date();// calculate the remaining time until expirationlong remainingTime expirationTime.getTime() - currentTime.getTime();// refresh the token if it expires within the next 5 minutesreturn remainingTime 5 * 60 * 1000; }private String generateNewAccessToken(String userId) {// generate a new access token with a new expiration timeDate expirationTime new Date(System.currentTimeMillis() ACCESS_TOKEN_EXPIRATION_TIME);String accessToken generateAccessToken(userId, expirationTime);return accessToken; }在这个示例中getAccessToken方法接收HttpServletRequest对象作为参数并使用extractAccessTokenFromRequest方法从请求中提取JWT访问令牌。然后它使用isAccessTokenExpired方法检查JWT的过期时间是否已过期。如果过期它使用extractUserIdFromAccessToken方法从JWT中提取用户ID并使用generateNewAccessToken方法生成一个新的JWT访问令牌。如果JWT尚未过期但即将到期则使用shouldRefreshAccessToken方法检查JWT是否需要更新。如果是这样它使用相同的流程生成一个新的JWT访问令牌。 学习总结 学习并且了解了什么是JWT学会了JWT基本使用及常见问题的解决思路 感谢 感谢官方文章《JWT介绍》
http://www.zqtcl.cn/news/734194/

相关文章:

  • 谁能给个网站谢谢wordpress 主题 后门
  • 学校网站建设目的seo教学免费课程霸屏
  • 会计公司网站模板微信网站如何制作软件
  • 烟台做网站多少钱.net网站做增删改
  • 什么网站专门做软件的深圳电商网站制作
  • 局域网做网站家装公司哪家比较好
  • 免费的行情软件网站在线使用wordpress视频分享
  • 内容平台策划书网站优化公司推荐
  • 怎么在阿里巴巴网站做公司wordpress伪静态404
  • 配置 tomcat 做网站网站建设用什么语言
  • 大型的营销型网站建设怎么选择网站建设公司
  • 怎么用网站源码建站友情链接交换方式有哪些
  • 国外免费网站服务器链接幼教网站建设分析
  • 做药品网站有哪些陕西专业网站建设价格
  • 网络公司做网站网站 服务器选择
  • 湖南省重点建设项目办公室网站河南省住建局官网
  • 建设网站企业网上银行登录入口官方论坛系统
  • 嘉定建设机械网站合肥制作网页设计
  • 外链网站有哪些空港经济区内的建设工程网站
  • 企业网站开发价阿里云快速备份网站
  • 大型电子商务网站建设成本ai网页生成
  • 网页播放视频 网站开发常用网站搜索引擎
  • 制作一个购物网站要多少钱做创意小视频的网站
  • 淇县网站建设软件定制流程
  • 17网站一起做网店代发流程wordpress悬浮 联系
  • 如何查网站外链快速开发平台 免费开源
  • 做网站有哪些流程怎么做网站电影
  • 做街机棋牌上什么网站发广告网站策划和运营
  • 建网站是什么专业类别阳江网红人物
  • 网站建设工作描述株洲市建设质监站网站