Pig4Cloud之检验token

本文介绍了一种前端实现的令牌验证与自动刷新机制。该机制通过定时任务检查令牌的有效期,并在剩余时间不足半小时时自动发起刷新请求。此外,还详细介绍了Spring Security中BearerTokenAuthenticationFilter的工作原理。

前端校验请求

/src/page/index/index.vue

refreshToken() {
      this.refreshTime = setInterval(() => {
        checkToken(this.refreshLock, this.$store)
      }, 10000)
    }

checkToken

/**
 * 校验令牌,若有效期小于半小时自动续期
 * 
 * 定时任务请求后端接口返回实际的有效时间,不进行本地计算避免 客户端和服务器机器时钟不一致
 * @param refreshLock
 */
export const checkToken = (refreshLock, $store) => {
  const token = store.getters.access_token
  // 获取当前选中的 basic 认证信息
  let basicAuth = getStore({name: 'basicAuth'})

  if(validatenull(token) || validatenull(basicAuth)){
      return;
  }

  request({
    url: '/auth/token/check_token',
    headers: {
      isToken: false,
      Authorization: basicAuth
    },
    method: 'get',
    params: {token}
  }).then(response => {
    const expire = response && response.data && response.data.exp
    if (expire) {
      const expiredPeriod = expire * 1000 - new Date().getTime()
      console.log('当前token过期时间', expiredPeriod, '毫秒')
      //小于半小时自动续约
      if (expiredPeriod <= website.remainingTime) {
        if (!refreshLock) {
          refreshLock = true
          $store.dispatch('RefreshToken')
            .catch(() => {
              clearInterval(this.refreshTime)
            })
          refreshLock = false
        }
      }
    }
  }).catch(error => {
    console.error(error)
  })
}

流程

当用户携带token 请求资源服务器的资源时,Spring Security 拦截token,进行token 和 userdetails 匹配过程,把无状态的token 转化成具体用户

image

BearerTokenAuthenticationFilter

https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/oauth2/server/resource/web/BearerTokenAuthenticationFilter.html
作为一个OncePerRequestFilter核心逻辑在doFilterInternal中。

@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {
		String token;
		try {
			token = this.bearerTokenResolver.resolve(request);
		}
		catch (OAuth2AuthenticationException invalid) {
			this.logger.trace("Sending to authentication entry point since failed to resolve bearer token", invalid);
			this.authenticationEntryPoint.commence(request, response, invalid);
			return;
		}
		if (token == null) {
			this.logger.trace("Did not process request since did not find bearer token");
			filterChain.doFilter(request, response);
			return;
		}

		BearerTokenAuthenticationToken authenticationRequest = new BearerTokenAuthenticationToken(token);
		authenticationRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));

		try {
			AuthenticationManager authenticationManager = this.authenticationManagerResolver.resolve(request);
			Authentication authenticationResult = authenticationManager.authenticate(authenticationRequest);
			SecurityContext context = SecurityContextHolder.createEmptyContext();
			context.setAuthentication(authenticationResult);
			SecurityContextHolder.setContext(context);
			this.securityContextRepository.saveContext(context, request, response);
			if (this.logger.isDebugEnabled()) {
				this.logger.debug(LogMessage.format("Set SecurityContextHolder to %s", authenticationResult));
			}
			filterChain.doFilter(request, response);
		}
		catch (AuthenticationException failed) {
			SecurityContextHolder.clearContext();
			this.logger.trace("Failed to process authentication request", failed);
			this.authenticationFailureHandler.onAuthenticationFailure(request, response, failed);
		}
	}

1.拦截请求进行鉴权

BearerTokenAuthenticationFilter 拦截所有资源服务器的请求。
解析 header 或者参数中的 access_token 字段
image

根据access_token 构造出来 BearerTokenAuthenticationToken 认证对象
image

请求authenticationManager.authenticate(authenticationRequest);进行鉴权。
image

2.鉴权操作

BearerTokenAuthenticationFilter解析 Authentication: Bearer {token} 中的token,交给 OpaqueTokenAuthenticationProvider

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
	if (!(authentication instanceof BearerTokenAuthenticationToken)) {
		return null;
	}
	BearerTokenAuthenticationToken bearer = (BearerTokenAuthenticationToken) authentication;
	OAuth2AuthenticatedPrincipal principal = getOAuth2AuthenticatedPrincipal(bearer);
	AbstractAuthenticationToken result = convert(principal, bearer.getToken());
	result.setDetails(bearer.getDetails());
	this.logger.debug("Authenticated token");
	return result;
}
	
private OAuth2AuthenticatedPrincipal getOAuth2AuthenticatedPrincipal(BearerTokenAuthenticationToken bearer) {
	try {
		return this.introspector.introspect(bearer.getToken());
	}
	catch (BadOpaqueTokenException failed) {
		this.logger.debug("Failed to authenticate since token was invalid");
		throw new InvalidBearerTokenException(failed.getMessage(), failed);
	}
	catch (OAuth2IntrospectionException failed) {
		throw new AuthenticationServiceException(failed.getMessage(), failed);
	}
}

OpaqueTokenAuthenticationProvider 委托 OpaqueTokenIntrospector introspect 去校验 token。

PigRedisOAuth2AuthorizationService 通过token value 查询 认证中心下发令牌时 存储的用户认证信息.
image
调用RedisOAuth2AuthorizationServicefindByToken

	@Override
	@Nullable
	public OAuth2Authorization findByToken(String token, @Nullable OAuth2TokenType tokenType) {
		Assert.hasText(token, "token cannot be empty");
		Assert.notNull(tokenType, "tokenType cannot be empty");
		redisTemplate.setValueSerializer(RedisSerializer.java());
		return (OAuth2Authorization) redisTemplate.opsForValue().get(buildKey(tokenType.getValue(), token));
	}

博客园
腾讯云
掘金
简书

<think>嗯,用户想了解或者使用Pig4Cloud相关的信息,特别是教程和介绍。首先,我需要确认用户的需求是什么。他们可能是一个开发者,正在寻找一个基于Spring Cloud的权限管理系统,或者是想了解如何快速搭建微服务架构。用户提到的Pig4Cloud是基于Spring Security的实践,可能他们需要知道如何集成安全模块,或者是系统的架构设计。 接下来,我应该先介绍Pig4Cloud的基本情况,包括它的技术栈和核心功能。根据提供的引用,Pig4Cloud使用了Spring Cloud 2022、Spring Boot3、Alibaba组件和MyBatisPlus,支持SAAS的RBAC权限管理,还有容器化技术和生产实践如Lambda等。这些都是关键点,需要简明扼要地概括。 然后,用户可能需要入门教程,所以分步骤说明如何快速启动。引用3提到了启动流程,涉及SecurityAutoConfiguration和SecurityFilterChain的构建,这里可能需要简化,让用户知道克隆代码库、配置数据库和启动核心模块即可。同时,引用5中的代码示例可以帮助他们理解数据操作,比如使用UpdateWrapper进行更新,这时候可能需要提到MyBatisPlus的使用方法。 接下来,系统架构部分需要解释各个模块的作用,比如认证中心、网关、业务模块等,这样用户能了解整体结构。安全机制部分,引用4详细描述了登录流程和Filter链,这里可以总结OAuth2和JWT的使用,以及FilterChainProxy的处理流程,但不用太深入,保持易懂。 关于生产实践,容器化支持和代码规范是重点,用户可能关心如何部署到Kubernetes或者Docker,以及代码风格是否符合团队要求。最后,相关的问题部分需要引导用户深入,比如权限管理如何扩展,如何处理高并发,或者如何定制安全策略,这些都能帮助他们进一步探索。 需要确保回答结构清晰,分点说明,并且引用正确的来源。同时,避免使用过多技术术语,保持语言通俗。还要检查是否符合用户的要求,比如使用中文,正确的LaTeX格式,以及生成相关问题。可能还需要确认引用的标记是否正确,比如引用3和引用4对应启动流程和登录流程的部分。 最后,总结用户可能需要的资源,比如官方文档和社区支持,帮助他们进一步学习。整个思考过程需要确保信息准确,基于提供的引用内容,同时以用户友好的方式呈现,解决他们的核心问题。</think>### Pig4Cloud 介绍与使用教程 #### 一、Pig4Cloud 基础介绍 Pig4Cloud 是基于 Spring Cloud 微服务架构的企业级开发平台,主要包含以下核心特性: 1. **技术栈** - 采用 $Spring\ Cloud\ 2022 + Spring\ Boot\ 3$ 最新框架 - 集成 MyBatis-Plus 实现 ORM 层高效开发 - 支持容器化部署($Docker/Kubernetes$) 2. **权限管理** - 基于 SAAS 模式的 RBAC 权限系统[^1] - 支持 OAuth2 协议和 JWT 令牌认证[^4] - 提供细粒度的数据权限控制 3. **生产实践** - 内置 Lambda、Stream API 等现代化编程模式 - 提供 Webflux 响应式编程支持 #### 二、快速入门教程 ##### 步骤1:环境准备 ```bash # 克隆代码库 git clone https://github.com/pig4cloud/pig.git ``` 需配置 MySQL 数据库和 Redis 缓存服务。 ##### 步骤2:核心模块启动 1. **认证中心 (pig-auth)** 引用[^3]中描述的启动流程: ```java // SecurityAutoConfiguration 加载安全配置 @Configuration @ConditionalOnClass(WebSecurityConfigurerAdapter.class) public class SecurityAutoConfiguration { // 自动构建 SecurityFilterChain } ``` 2. **网关服务 (pig-gateway)** 负责路由分发与请求过滤[^2]。 ##### 步骤3:数据操作示例 引用[^5]中 MyBatis-Plus 的更新操作: ```java UpdateWrapper<Station> wrapper = new UpdateWrapper<>(); wrapper.lambda().eq(Station::getId, id) .set(Station::getPlace, "北京") .set(Station::getNumber, null); stationService.update(wrapper); ``` #### 三、系统架构解析 $$系统架构 = 认证中心 + 网关服务 + 业务模块 + 监控体系$$ 通过 $OAuth2.0$ 实现统一认证,使用 $Spring\ Security$ 的 FilterChainProxy 进行请求过滤。 #### 四、安全机制详解 1. **登录流程** - 请求经过 19 层安全过滤器链 - 核心过滤器: - `OAuth2ClientAuthenticationFilter`(客户端校验) - `BearerTokenAuthenticationFilter`(JWT 解析) 2. **令牌签发** 采用 HMAC-SHA256 算法生成 JWT: $$token = header(base64).payload(base64).signature(加密)$$ #### 五、生产实践建议 1. **容器化部署** ```dockerfile FROM openjdk:17 COPY target/pig-auth.jar /app.jar ENTRYPOINT ["java","-jar","/app.jar"] ``` 2. **代码规范** 强制使用 Checkstyle 进行代码格式校验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值