[Spring Cloud] (3)gateway令牌token拦截器

文章目录

    • 集成redis
      • Nacos配置增加
    • redis配置
    • 配置pom
      • redis配置RedisConfig
      • redis序列化工具FastJson2JsonRedisSerializer
      • 测试
    • 令牌校验拦截器
      • nacos配置
      • 拦截器代码
      • 微服务登录接口实现
    • 最终效果-登录接口与数据接口

本文gateway与微服务已开源到gitee
杉极简/gateway网关阶段学习

在Gateway(网关)与微服务架构中,令牌校验器(Token Validator)通常扮演着至关重要的角色,它的作用主要包括:

  1. 身份验证:令牌校验器确保只有拥有有效令牌的用户或服务才能访问微服务。这是保护后端服务的第一道防线。
  2. 权限控制:令牌中可能包含了用户的权限信息,校验器可以检查用户是否有足够的权限来访问特定的资源或执行特定的操作。
  3. 会话管理:在用户与服务之间维护会话状态,确保用户在一段时间内的请求可以关联到同一个会话。
  4. 单点登录(SSO):如果多个微服务共享同一个认证系统,令牌校验器可以帮助实现单点登录,用户只需要登录一次就可以访问所有服务。
  5. 负载减轻:通过在网关层面校验令牌,可以减轻微服务的负担,因为微服务不需要再进行令牌的校验,可以专注于业务逻辑的处理。
  6. 安全性增强:令牌校验器可以确保令牌的传输和使用符合安全标准,比如使用HTTPS传输,确保令牌不被窃取或篡改。
  7. 跨域处理:在网关层面处理跨域资源共享(CORS)问题,确保来自不同域的请求能够正常访问微服务。
  8. 集中管理:通过在网关处统一校验令牌,可以集中管理认证策略和令牌格式,便于维护和更新。
  9. 监控与日志记录:在令牌校验的过程中,可以记录相关的访问日志,便于后续的监控和分析。

令牌校验器通常是集成在API网关中的一个组件,它作为微服务架构中的守门人,确保所有进入微服务网络的请求都是合法和安全的。

集成redis

Nacos配置增加

Nacos中增加如下配置

  redis:host: localhostport: 6379password: 123456timeout: 6000

image.png

redis配置

image.png

配置pom

<!--redis-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

redis配置RedisConfig

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;/*** redis配置** @author fir*/
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport
{@Bean@SuppressWarnings(value = { "unchecked", "rawtypes" })public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory){RedisTemplate<Object, Object> template = new RedisTemplate<>();template.setConnectionFactory(connectionFactory);FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);ObjectMapper mapper = new ObjectMapper();mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);serializer.setObjectMapper(mapper);// 使用StringRedisSerializer来序列化和反序列化redis的key值template.setKeySerializer(new StringRedisSerializer());template.setValueSerializer(serializer);// Hash的key也采用StringRedisSerializer的序列化方式template.setHashKeySerializer(new StringRedisSerializer());template.setHashValueSerializer(serializer);template.afterPropertiesSet();return template;}
}

redis序列化工具FastJson2JsonRedisSerializer

package com.fir.gateway.config.redis;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.util.Assert;import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;/*** Redis使用FastJson序列化** @author fir*/
public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T>
{public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;private final Class<T> clazz;public FastJson2JsonRedisSerializer(Class<T> clazz){super();this.clazz = clazz;}@Overridepublic byte[] serialize(T t) throws SerializationException{if (t == null){return new byte[0];}return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);}@Overridepublic T deserialize(byte[] bytes) throws SerializationException{if (bytes == null || bytes.length <= 0){return null;}String str = new String(bytes, DEFAULT_CHARSET);return JSON.parseObject(str, clazz);}public void setObjectMapper(ObjectMapper objectMapper){Assert.notNull(objectMapper, "'objectMapper' must not be null");}protected JavaType getJavaType(Class<?> clazz){return TypeFactory.defaultInstance().constructType(clazz);}
}

测试

通过一下代码进行测试,通过测试redis已经集成成功,详情如下:

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;import javax.annotation.Resource;@SpringBootTest
public class RedisTest {@Resourceprivate RedisTemplate<String,Object> redisTemplate;@Testvoid set(){redisTemplate.opsForValue().set("name123", "value123");}@Testvoid get(){Object object = redisTemplate.opsForValue().get("name123");System.out.println(object);}
}

image.png

令牌校验拦截器

image.png

nacos配置

首先在nacos中新增tokenCheckwhiteUrls配置项**,**如下配置:

global:# 全局异常捕捉-打印堆栈异常printStackTrace: true# 令牌头变量名称token: Authorization# 令牌校验tokenCheck: true# 不需要进行过滤的白名单whiteUrls:- /tick/auth/login- /ws

拦截器代码

import com.fir.gateway.config.GlobalConfig;
import com.fir.gateway.config.exception.CustomException;
import com.fir.gateway.config.result.AjaxStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;import javax.annotation.Resource;
import java.util.List;/*** 令牌token校验拦截器** @author fir*/
@Slf4j
@Component
public class AuthorizationFilter implements GlobalFilter, Ordered {/*** 网关参数配置*/private GlobalConfig globalConfig;@Resourceprivate RedisTemplate<String, Object> redisTemplate;@Autowiredpublic void someComponent(GlobalConfig globalConfig) {this.globalConfig = globalConfig;}@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {log.info("登录信息校验:start");// 判断token是否存在,且是否过期boolean tokenKey = globalConfig.isTokenCheck();if (tokenKey) {// 白名单路由判断ServerHttpRequest request = exchange.getRequest();String path = request.getPath().toString();List<String> whiteUrls = globalConfig.getWhiteUrls();if (!whiteUrls.contains(path)) {String tokenHeader = globalConfig.getTokenHeader();String token = exchange.getRequest().getHeaders().getFirst(tokenHeader);if (token == null || token.isEmpty()) {log.error("token为空");throw new CustomException(AjaxStatus.EXPIRATION_TOKEN);}Object obj = redisTemplate.opsForValue().get(token);if (obj != null) {log.info("登录信息校验:true");} else {log.error("token已失效");throw new CustomException(AjaxStatus.EXPIRATION_TOKEN);}} else {log.info("登录信息校验:true,白名单");}} else {log.info("登录信息校验:true,验证已关闭");}return chain.filter(exchange);}@Overridepublic int getOrder() {return -290;}
}

微服务登录接口实现

微服务同样需要集成redis,集成方式与gateway一样

package com.fir.nacos.controller;import com.alibaba.nacos.common.utils.StringUtils;
import com.fir.nacos.config.result.AjaxResult;
import com.fir.nacos.config.result.AjaxStatus;
import com.fir.nacos.entity.LoginResultDTO;
import com.fir.nacos.service.IAuthService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;/*** @author fir*/
@Slf4j
@Api(tags = "系统接口")
@RestController
@RefreshScope
@RequestMapping("/auth")
public class AuthController {@Resourceprivate IAuthService iAuthService;/*** 用户统一登陆** @param username 用户* @param password 密码* @return 登录信息/登录失败信息*/@ApiOperation("登录接口")@ApiImplicitParams({@ApiImplicitParam(name = "username", value = "用户"),@ApiImplicitParam(name = "password", value = "密码")})@RequestMapping("/login")public AjaxResult login(String username, String password) {LoginResultDTO loginResultDTO;if(StringUtils.isNoneBlank(username) && StringUtils.isNoneBlank(password)){loginResultDTO = iAuthService.login(username, password);}else {return AjaxResult.error(AjaxStatus.NULL_LOGIN_DATA);}return AjaxResult.success(loginResultDTO);}
}
/*** 用户统一登录** @param username 账号* @param password 密码* @return 登录信息*/
@Override
public LoginResultDTO login(String username, String password){LoginResultDTO loginResultDTO = new LoginResultDTO();if(StringUtils.isNoneBlank(username) && StringUtils.isNoneBlank(password)){// 此处简单处理,根据实际的项目做更改if(username.equals("fir") && password.equals("123456")){// 生成 Token (可用多种方式例如jwt,此处不额外集成)String token = "Bearer " + username + "token";ConnectDTO connectDTO = ConnectDTO.builder().name(username).build();Object o = JSONObject.toJSONString(connectDTO);redisTemplate.opsForValue().set(token, o, globalConfig.getTimeNum(), globalConfig.timeUnit);loginResultDTO = LoginResultDTO.builder().token(token).build();}}return loginResultDTO;
}

最终效果-登录接口与数据接口

此时如果不登录,则会被拦截
image.png

此时需要先获取到token之后,在数据接口的访问中,增加一个令牌请求头参数Authorization
image.png
image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/309595.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

陪玩小程序开发 运营级别陪玩成品搭建 支持二开源码交付 游戏陪玩系统,游戏陪玩源码,游戏陪玩语音社交源码

陪玩系统是一种新兴的服务模式&#xff0c;主要通过线上预约和线下社交、陪伴、助娱、分享、指导等方式为用户提供服务。这种服务模式适用于多种场景&#xff0c;包括家庭陪护、吃饭陪聊、景点伴游、网游陪练、健身指导、线下桌游、酒吧K歌、逛街观影、剧本密室、聚会轰趴、美食…

三年了,期待下一个三年

第一个三年 时间好快&#xff0c;距离我发布我第一篇文章都已经三个年头了。 转眼也从大一新生变成了大四打工人。 在平台上发布博客&#xff0c;分享自己的项目、学习思路、解决的bug都带给我很多收获。 平台上的粉丝&#xff0c;阅读量等&#xff0c;也让我的简历更加出彩。…

绝地求生:杜卡迪来了,这些摩托车技巧不学一下吗?

摩托车在远古版本和现在完全不一样&#xff0c;虽然容易翻车造就了一批玩家“摩托杀手”的外号&#xff0c;但是速度可比今天快多了。 后来在蓝洞的削弱了其加速度&#xff0c;虽然资料上写着最高时速155km/h&#xff0c;但是平时游戏中一般只能拉到110~120km/h。这里写一点摩托…

最新版守约者二级域名分发系统

主要功能 二级域名管理&#xff1a; 我们的系统提供全面的二级域名管理服务&#xff0c;让您轻松管理和配置二级域名。 域名分发&#xff1a;利用我们先进的域名分发技术&#xff0c;您可以自动化地分配和管理域名&#xff0c;确保每个用户或客户都能及时获得所需的域名资源。…

Ceph [OSDI‘06]论文阅读笔记

原论文&#xff1a;Ceph: A Scalable, High-Performance Distributed File System (OSDI’06) Ceph简介及关键技术要点 Ceph是一个高性能、可扩展的分布式文件系统&#xff0c;旨在提供出色的性能、可靠性和可扩展性。为了最大化数据和元数据管理的分离&#xff0c;它使用了一…

网络篇06 | 应用层 自定义协议

网络篇06 | 应用层 自定义协议 01 固定协议设计&#xff08;简化版&#xff09;1&#xff09;总体设计2&#xff09;值设计 02 可变协议设计&#xff08;进阶版&#xff09;1&#xff09;固定头&#xff08;Fixed Header&#xff09;2&#xff09;可变头&#xff08;Variable H…

5、LMDeploy 量化部署 LLMVLM实战(homework)

基础作业&#xff08;结营必做&#xff09; 完成以下任务&#xff0c;并将实现过程记录截图&#xff1a; 配置lmdeploy运行环境 由于环境依赖项存在torch&#xff0c;下载过程可能比较缓慢。InternStudio上提供了快速创建conda环境的方法。打开命令行终端&#xff0c;创建一…

简单认识Git(dirsearch、githack下载),git泄露(ctfhub)

目录 dirsearch下载地址: githack下载&#xff08;一次不成功可多试几次&#xff09; 一、什么是Git 1.git结构 2.git常用命令及示例 3.Git泄露原理 二、Git泄露 1.Log 2.Stash 3.Index 工具准备&#xff1a;dirsearch、githack dirsearch下载地址: GitHub - mauroso…

数字乡村创新实践探索农业现代化与乡村振兴新路径:科技赋能农村全面振兴与农民幸福新篇章

随着信息技术的飞速发展&#xff0c;数字乡村成为推动农业现代化与乡村振兴的重要战略举措。科技赋能下的数字乡村创新实践&#xff0c;不仅提升了农业生产的智能化水平&#xff0c;也为乡村治理和农民生活带来了翻天覆地的变化。本文旨在探讨数字乡村创新实践在农业现代化与乡…

OpenCV的查找命中或未命中

返回:OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇:OpenCV4.9更多形态转换 下一篇:OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 目标 在本教程中&#xff0c;您将学习如何使用 Hit-or-Miss 转换&#xff08;也称为 Hit-and-Miss 转…

JavaScript知识点 --javaweb学习笔记

什么是Javascript? JavaScript(简称:JS)是一门跨平台、面向对象的脚本语言。是用来控制网页行为的&#xff0c;它能使网页可交互JavaScript 和Java 是完全不同的语言&#xff0c;不论是概念还是设计。但是基础语法类似JavaScript在1995 年由 Brendan Eich 发明&#xff0c;并…

护眼台灯什么品牌好?推荐目前比较好用的护眼台灯

现在孩子的近视率很高&#xff0c;尤其是儿童青少年居多&#xff0c;上了小学作业都变多了&#xff0c;很多孩子经常需要学习到很晚&#xff0c;不过家长们在重视教育质量的同时&#xff0c;有注意到孩子学习时的光线适合学习吗&#xff1f;用眼过度和光线不合适都容易导致近视…

Java快速入门系列-9(Spring框架与Spring Boot —— 深度探索及实践指南)

第九章:Spring框架与Spring Boot —— 深度探索及实践指南 9.1 Spring框架概述9.2 Spring IoC容器9.3 Spring AOP9.4 Spring MVC9.5 Spring Data JPA/Hibernate9.6 Spring Boot快速入门与核心特性9.7 Spring Boot的自动配置与启动流程详解9.8 创建RESTful服务与数据库交互实践…

OpenHarmony南向开发案例:【智能垃圾桶】

样例简介 智能垃圾桶可以通过数字管家应用来监测垃圾桶当前可用容量&#xff0c;提醒主人及时处理垃圾&#xff1b;通过日程管家可以实现和其他智能设备联动。 核心组件位置功能距离传感器置于垃圾桶盖内侧感应垃圾量红外传感器置于垃圾桶前端感应是否有人靠近光敏电阻开发板…

0.25W 3KVDC 隔离单、双输出 DC/DC SMD 型电源模块 ——TPVT-W2 系列

TPVT-W2系列是一款标准的表面贴装电源模块&#xff0c;完全实现采用全自动贴片机来组装和满足回流焊工艺&#xff0c;大大提高产能和降低人工费用。此系列产品小&#xff0c;效率高&#xff0c;低输出纹波及提供3000V以上的直流电压隔离&#xff0c;SMD封装。

第一节:什么是操作系统

什么是操作系统 一、一台计算机的组成部分1、计算机能干啥2、谈谈计算机硬件 二、什么是操作系统三、学习操作系统的层次 一、一台计算机的组成部分 如下图所示&#xff1a; 这就是就是构成一台计算机的组成部分 1、计算机能干啥 ∙ \bullet ∙计算机是我们专业吃饭的家伙&a…

微信小程序公共组件封装使用

1.在components目录下创建公共组件&#xff0c;以navbar为例 2.完成组件功能 3.调用&#xff0c;如果很多地方都会用到&#xff0c;建议放全局&#xff0c;如果不是则放在需要引用的文件中 3.1全局引用&#xff0c;在app.json做全局引用配置 3.2局部引用&#xff0c;在需要引入…

密码学与密码安全:理论与实践

title: 密码学与密码安全&#xff1a;理论与实践 date: 2024/4/10 21:22:31 updated: 2024/4/10 21:22:31 tags: 密码学加密算法安全协议密码分析密码安全实际应用未来发展 第一章&#xff1a;密码学基础 1.1 密码学概述 密码学是研究如何保护信息安全的学科&#xff0c;旨在…

C语言疑难点

AScii码&#xff1a; \0 、0、‘0’的区别&#xff1a;‘\0’转义字符的ascii码值是0&#xff0c;’\0’与数字0相同&#xff0c;但不与‘0’相同&#xff0c;‘0’的ascii码值是48&#xff0c;‘a字符的值是97&#xff08;ASCII表&#xff09; 字符串长度为5&#xff0c;大小…

房贷还款(C语言)

一、运行结果&#xff1b; 二、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h> # include <math.h>int main() {//初始化变量值&#xff1b;double m, r 0.01;float d 300000;float p 6000;//运算还款所需月份&#xff1b;m log10…