【用户登录】网关,token,全局异常处理

本文详细介绍了微服务网关的搭建过程,包括登录验证、微服务路由配置、统一Token处理、全局过滤器的添加以及Token的解析。在登录验证中,实现了参数校验、用户查询及Token生成。网关配置了路由转发规则,通过Nacos进行服务发现。全局过滤器用于Token校验和解析,确保请求的安全性。此外,还涉及到了ThreadLocal工具类的使用和全局异常处理机制,确保系统稳定运行。
摘要由CSDN通过智能技术生成

一, 登录

引导类:

@SpringBootApplication
//如果默认手动指定扫描的包 默认扫描包的规则则失效
@ComponentScan(
basePackages =
{
..web”,
..system”,
}
)
@MapperScan(“..system.mappers”)
public class SystemApplication {
public static void main(String[] args) {
SpringApplication.run(SystemApplication.class, args);
}
}

Controller层

@RestController
public class LoginController {

@Autowired
private UserService userService;

@PostMapping("/login")
public ResponseResult login(@RequestBody LoginDto dto) {
    return userService.login(dto);
}

}

ServiceImpl层

@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;

//用户登录
@Override
public ResponseResult login(LoginDto dto) {

     //1. 验证请求参数  做非空判断
    String phone = dto.getUsername();//登录手机号
    String password = dto.getPassword();//登录密码
    String utype = dto.getUtype();//登录手机号
    
    if (StringUtils.isEmpty(password) || 
            StringUtils.isEmpty(phone)||
            StringUtils.isEmpty(utype)) {
        throw new BusinessException(ErrorCode.LOGINERROR);//用户名或者密码错误
    }

     //2.根据根据请求的参数 从库里查询用户对象
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(User::getPhone, phone);//登录手机号
    wrapper.eq(User::getUtype, utype);//登录手机号
    User user = userMapper.selectOne(wrapper);

    //3 判断 用户是否存在
    //3-1用户不存在  抛错误提示
    if (StringUtils.isEmpty(user)) {
        throw new BusinessException(ErrorCode.LOGINERROR);
    }
     //3-2 用户存在 则对传入的密码进行md5加密 并且与库里的进行对比
    String mdPassword = DigestUtil.md5Hex(password);
    if (!mdPassword.equals(user.getPassword())) {
        throw new BusinessException(ErrorCode.LOGINERROR);
    }
    
    //4.密码比对成功 ,生成token字符串
    //4-1 构建map集合
    HashMap<String, Object> hashMap = new HashMap<>();
    hashMap.put("userId", user.getId());//用户名
    hashMap.put("companyId", user.getCompanyId());//机构Id
    hashMap.put("companyName", user.getCompanyName());//机构名
    
    //4-2.存入jwt  ,并且设置有效期(这里设置24小时)
    String token = JwtUtils.createToken(hashMap, 60 * 24);

    //返回结果
    LoginVo vo = new LoginVo();
    vo.setAccess_token(token);
    vo.setUsername(user.getName());
    return ResponseResult.okResult(vo);
}

}

二,搭建微服务网关

网关就是系统的入口,封装了应用程序的内部结构,为客户端提供统一服务,一些与业务本身功能无关的公共逻辑可以在这里实现,诸如认证、鉴权、监控、缓存、负载均衡、流量管控、路由转发等。学成在线也是通过网关介入所有请求,进行路由转发
在这里插入图片描述
引入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

<dependency>
    <groupId>com.xuecheng</groupId>
    <artifactId>xc-framework-commons</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>
## 路由配置

server:
port: 60010
spring:
application:
name: xc-gateway
cloud:
nacos:
discovery:
server-addr: 192.168.136.150:8848 #注册中心nacos地址
gateway:
globalcors:
cors-configurations:
'[/]': # 匹配所有请求
allowedOrigins: “*” #跨域处理 允许所有的域
allowedMethods: # 支持的方法
- GET
- POST
- PUT
- DELETE
routes:
- id: content
uri: lb://xc-content-service
predicates:
- Path=/content/

filters:
- StripPrefix=1
- id: system
uri: lb://xc-system-service
predicates:
- Path=/system/**
filters:
- StripPrefix=1
- id: media
uri: lb://xc-media-service
predicates:
- Path=/media/**
filters:
- StripPrefix=1
- id: auth
uri: lb://xc-system-service
predicates:
- Path=/auth/**
filters:
- StripPrefix=1
- id: basic
uri: lb://xc-basic-service
predicates:
- Path=/basic/**
filters:
- StripPrefix=1
- id: order
uri: lb://xc-order-service
predicates:
- Path=/order/**
filters:
- StripPrefix=1
- id: teaching
uri: lb://xc-teaching-service
predicates:
- Path=/teaching/**
filters:
- StripPrefix=1
- id: search
uri: lb://xc-search-service
predicates:
- Path=/search/**
filters:
- StripPrefix=1
- id: learning
uri: lb://xc-learning-service
predicates:
- Path=/learning/**
filters:
- StripPrefix=1
logging:
level:
com.alibaba.nacos.client.*: WARN
引导类:
@SpringBootApplication
public class GatewayApplicaton {
public static void main(String[] args) {

    SpringApplication.run(GatewayApplicaton.class, args);
}

}

三,统一Token处理

登录验证:

网关就是系统的入口,封装了应用程序的内部结构,为客户端提供统一服务,一些与业务本身功能无关的公共逻辑可以在这里实现,诸如认证、鉴权、监控、缓存、负载均衡、流量管控、路由转发等。

执行流程:

1. 请求发送到网关,在网关层进行token的验证和解析
2. 网关转发到微服务,这是携带新的请求头payload
3. 微服务拦截器获取payload转化java对象,存入Threadlocal
4. controller及后续方法,直接从当前线程获取

在这里插入图片描述

四,网关登录校验

GlobalFilter 全局过滤器,不需要在配置文件中配置,系统初始化时加载,并作用在每个路由上。

  • 对于不需要鉴权的请求放行
  • 获取请求头中的Authorization请求头
  • 校验token,如果检验失败则响应401(未登录)
  • 为了方便后续的操作,在网关中解析token。将数据转为json向后续微服务传递

五,在网关模块添加全局过滤器

全局过滤器详见:https://blog.csdn.net/apple_69693064/article/details/127020499

六,统一token解析

1.编写拦截器

@Component
@Slf4j
public class TokenInterceptor implements HandlerInterceptor {

    //1.进入controller方法之前执行
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String payload = request.getHeader("payload");
        if (StringUtils.isEmpty(payload)) {
        return true;
        }
        //转换成AuthInfo对象
        String json = URLDecoder.decode(payload, "UTF-8");

        log.info("json"+json);
        AuthInfo info = JSON.parseObject(json, AuthInfo.class);
        log.info("json"+json);
        AuthInfoHolder.setAuthInfo(info);//存入ThreadLocal线程中
        return true;//放行请求
    }

    //2.Controller方法之后执行
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    //3.离开controller方法之后执行
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    AuthInfoHolder.remove();
    }
}

1.配置拦截器

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new TokenInterceptor())  // 添加拦截器
                .addPathPatterns("/**");    // 添加拦截的路径
    }
}

七,ThreadLocal工具类

详情见https://blog.csdn.net/apple_69693064/article/details/126916334

八,全局异常处理

详情见https://blog.csdn.net/apple_69693064/article/details/127020516

注意:在每个微服务中,都会使用统一异常处理和过滤器的相关代码逻辑。为了尽可能的复用代码,需要将公共的逻辑抽取到一个合适的公共模块下

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

上官玺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值