做门户网站用什么系统,thesis wordpress,无锡网站建设 微信,wordpress 插件play若微服务数量多#xff0c;如果每个服务都改动#xff0c;工作量大#xff0c;则可以只在网关和用户中心进行改动#xff0c;也是可以实现服务之间的跳转。 这种方式可以通过在网关服务中生成和验证 Sa-Token#xff0c;并将其与现有的 Token关联存储在 Redis 中。用户中心… 若微服务数量多如果每个服务都改动工作量大则可以只在网关和用户中心进行改动也是可以实现服务之间的跳转。 这种方式可以通过在网关服务中生成和验证 Sa-Token并将其与现有的 Token关联存储在 Redis 中。用户中心提供额外的接口来验证和生成新的 Sa-Token。 这样只需要改造网关和用户服务其他服务保持现状即可实现各个应用之间的跳转 实现方案 为了实现这个目标同时尽量减少对现有系统的改动可以在网关和用户中心进行必要的改动以确保用户在登录后能够在多个系统中无缝访问。 下面是详细的方案和步骤
一、用户中心改造
用户中心需要提供两个接口
登录接口用户登录并生成原有业务系统的 Token。Token 验证和 Sa-Token 生成接口验证原有 Token 并生成 Sa-Token。
1. 登录接口
RestController
RequestMapping(/auth)
public class AuthController {PostMapping(/login)public ResponseEntityMapString, Object login(RequestParam String username, RequestParam String password) {MapString, Object result new HashMap();// 进行用户名和密码校验if (checkCredentials(username, password)) {String originalToken generateOriginalToken(username); // 生成原有业务系统的 Tokenresult.put(originalToken, originalToken);return ResponseEntity.ok(result);}result.put(error, 登录失败);return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(result);}private boolean checkCredentials(String username, String password) {// 检查用户名和密码逻辑return true; // 假设校验成功}private String generateOriginalToken(String username) {// 生成原有业务系统的 Tokenreturn original-token;}
}2. Token 验证和 Sa-Token 生成接口
RestController
RequestMapping(/auth)
public class AuthController {Autowiredprivate RedisTemplateString, String redisTemplate;GetMapping(/check)public ResponseEntitySaResult checkToken(RequestParam String token) {// 验证原有 Tokenif (validateOriginalToken(token)) {String userId getUserIdFromOriginalToken(token);StpUtil.login(userId);String saToken StpUtil.getTokenValue();// 存储原有 Token 和 Sa-Token 的映射关系redisTemplate.opsForValue().set(sa-token: token, saToken);redisTemplate.opsForValue().set(original-token: saToken, token);return ResponseEntity.ok(SaResult.ok(Token 有效).set(saToken, saToken));}return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(SaResult.error(Token 无效));}private boolean validateOriginalToken(String token) {// 验证原有业务系统的 Tokenreturn true; // 假设校验成功}private String getUserIdFromOriginalToken(String token) {// 从原有业务系统的 Token 中解析出用户IDreturn parsed-user-id;}
}二、网关服务改造
网关服务需要在所有请求到达后端服务前进行原有 Token 的验证和 Sa-Token 的生成和验证。
1. 引入 Redis 依赖
确保网关服务的 pom.xml 文件中包含 Redis 依赖
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId
/dependency2. 配置 Redis
在 application.yml 文件中配置 Redis 连接信息
spring:redis:host: localhostport: 6379password: 3. 网关服务 Token 校验过滤器
Component
public class TokenFilter implements GlobalFilter, Ordered {Autowiredprivate RestTemplate restTemplate;Autowiredprivate RedisTemplateString, String redisTemplate;Overridepublic MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) {String originalToken exchange.getRequest().getHeaders().getFirst(Authorization);if (originalToken ! null) {String saToken redisTemplate.opsForValue().get(sa-token: originalToken);if (saToken null) {// 调用用户中心的接口生成 Sa-TokensaToken generateSaToken(originalToken);if (saToken null) {exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);return exchange.getResponse().setComplete();}}exchange.getRequest().mutate().header(Sa-Token, saToken).build();return chain.filter(exchange);}exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);return exchange.getResponse().setComplete();}private String generateSaToken(String originalToken) {// 调用用户中心的接口生成 Sa-TokenString url http://user-center/auth/check?token originalToken;ResponseEntitySaResult response restTemplate.getForEntity(url, SaResult.class);if (response.getStatusCode() HttpStatus.OK response.getBody().getCode() 200) {return response.getBody().get(saToken).toString();}return null;}Overridepublic int getOrder() {return -100;}
}三、工作流程 用户登录 用户通过用户中心的登录接口进行登录用户中心生成原有业务系统的 Token 并返回给前端。 请求网关 前端在请求其他服务时将原有的 Token 添加到请求头中发送请求到网关。 网关处理 网关拦截请求从请求头中获取原有的 Token。网关调用用户中心的 Token 验证接口来验证原有 Token 并生成 Sa-Token。将原有 Token 和 Sa-Token 的映射关系存储在 Redis 中。将 Sa-Token 添加到请求头中转发请求到后端服务。 后端服务 后端服务可以继续保持现有的 Token 逻辑不需要改动。所有的 Token 验证和生成逻辑都在网关和用户中心处理。
模块详细介绍
在上述方案中实现单点登录的关键步骤包括
用户中心提供接口验证原有 Token 并生成 Sa-Token通过 /auth/check 接口用户中心接收原有业务系统的 Token验证其有效性并生成新的 Sa-Token。网关服务拦截所有请求验证和生成 Sa-Token网关服务在接收到请求时首先检查请求头中的原有 Token并调用用户中心的 /auth/check 接口来验证 Token 并生成 Sa-Token将生成的 Sa-Token 存储在 Redis 中并添加到请求头中转发给后端服务。
这些步骤确保了用户在登录后可以使用原有 Token 进行验证并通过 Sa-Token 进行单点登录的验证从而实现了单点登录的效果。
具体的实现过程 用户登录生成原有业务系统的 Token 用户通过用户中心的登录接口进行登录。用户中心生成原有业务系统的 Token 并返回给前端。 网关服务处理用户请求 前端在请求其他服务时将原有的 Token 添加到请求头中发送请求到网关。网关服务拦截请求获取请求头中的原有 Token。 网关服务验证和生成 Sa-Token 网关服务调用用户中心的 /auth/check 接口验证原有 Token 的有效性。用户中心验证原有 Token 有效后生成 Sa-Token 并返回给网关服务。网关服务将原有 Token 和 Sa-Token 的映射关系存储在 Redis 中。网关服务将生成的 Sa-Token 添加到请求头中转发请求到后端服务。 后端服务处理请求 后端服务可以继续保持现有的 Token 验证逻辑不需要改动。所有的 Token 验证和生成逻辑都在网关和用户中心处理。
实现细节
1. 用户中心新增 Token 验证和生成 Sa-Token 接口
RestController
RequestMapping(/auth)
public class AuthController {Autowiredprivate RedisTemplateString, String redisTemplate;GetMapping(/check)public ResponseEntitySaResult checkToken(RequestParam String token) {// 验证原有 Tokenif (validateOriginalToken(token)) {String userId getUserIdFromOriginalToken(token);StpUtil.login(userId);String saToken StpUtil.getTokenValue();// 存储原有 Token 和 Sa-Token 的映射关系redisTemplate.opsForValue().set(sa-token: token, saToken);redisTemplate.opsForValue().set(original-token: saToken, token);return ResponseEntity.ok(SaResult.ok(Token 有效).set(saToken, saToken));}return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(SaResult.error(Token 无效));}private boolean validateOriginalToken(String token) {// 验证原有业务系统的 Tokenreturn true; // 假设校验成功}private String getUserIdFromOriginalToken(String token) {// 从原有业务系统的 Token 中解析出用户IDreturn parsed-user-id;}
}2. 网关服务 Token 校验过滤器
Component
public class TokenFilter implements GlobalFilter, Ordered {Autowiredprivate RestTemplate restTemplate;Autowiredprivate RedisTemplateString, String redisTemplate;Overridepublic MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) {String originalToken exchange.getRequest().getHeaders().getFirst(Authorization);if (originalToken ! null) {String saToken redisTemplate.opsForValue().get(sa-token: originalToken);if (saToken null) {// 调用用户中心的接口生成 Sa-TokensaToken generateSaToken(originalToken);if (saToken null) {exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);return exchange.getResponse().setComplete();}}exchange.getRequest().mutate().header(Sa-Token, saToken).build();return chain.filter(exchange);}exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);return exchange.getResponse().setComplete();}private String generateSaToken(String originalToken) {// 调用用户中心的接口生成 Sa-TokenString url http://user-center/auth/check?token originalToken;ResponseEntitySaResult response restTemplate.getForEntity(url, SaResult.class);if (response.getStatusCode() HttpStatus.OK response.getBody().getCode() 200) {return response.getBody().get(saToken).toString();}return null;}Overridepublic int getOrder() {return -100;}
}工作流程总结
用户登录并获取原有业务系统的 Token。用户在请求服务时携带原有 Token 发送请求到网关。网关验证原有 Token并通过用户中心生成 Sa-Token。网关将 Sa-Token 存储在 Redis 中并添加到请求头中转发给后端服务。后端服务保持现有逻辑不变网关和用户中心负责所有的 Token 验证和生成。
通过以上步骤达成了在现有系统中实现的目标同时最大限度地减少了对现有系统的改动。
五、总结 通过上述详细的改造步骤和代码示例可以在不改动后端服务的情况下实现单点登录。所有的 Token 验证和生成逻辑都集中在网关和用户中心实现了 Token 的统一管理和验证。这样既实现了项目之间跳转的目标又最大限度地减少了对现有系统的改造。