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

用户登录更新中:网关,token,全局异常处理

用户登录权限验证

  • 一, 登录
  • Controller层
  • ServiceImpl层
  • 二,搭建微服务网关
  • 三,统一Token处理
  • 四,网关登录校验
      • 五,在网关模块添加全局过滤器
  • 六,统一token解析
      • 1.编写拦截器
      • 1.配置拦截器
  • 七,ThreadLocal工具类
  • 八,全局异常处理

一, 登录

引导类:

@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

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

相关文章:

  • Unity Pico Neo3 基础开发流程
  • 图的刷题..
  • 机器学习个人总结(王道版)
  • 【Machine Learning】8.逻辑回归及其在分类问题的应用
  • ZYNQ之路--带你弄明白Vivado设计流程
  • 最大子数组和-前缀和/动态规划/分治/暴力-Java/c++
  • [JS]JavaScript 注释 输入输出语句
  • 网络笔记大全(超详细)
  • 网课题库接口使用
  • 【计算方法】python实现高斯消去、列主元高斯消去,LU分解分别求解线性方程组
  • 回归预测 | MATLAB实现GA-BP多输入单输出回归预测
  • Nmap的API和库文件
  • Linux命令 -文件权限配置的深入(chown/chmod/setfacl)
  • ubuntu安装selenium
  • React脚手架工具创建项目的详细介绍
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • 《微软的软件测试之道》成书始末、出版宣告、补充致谢名单及相关信息
  • 【347天】每日项目总结系列085(2018.01.18)
  • Angular 2 DI - IoC DI - 1
  • Idea+maven+scala构建包并在spark on yarn 运行
  • JavaScript对象详解
  • js作用域和this的理解
  • Laravel 实践之路: 数据库迁移与数据填充
  • spring boot下thymeleaf全局静态变量配置
  • vue从创建到完整的饿了么(18)购物车详细信息的展示与删除
  • Web Storage相关
  • webpack项目中使用grunt监听文件变动自动打包编译
  • 发布国内首个无服务器容器服务,运维效率从未如此高效
  • 关于extract.autodesk.io的一些说明
  • 软件开发学习的5大技巧,你知道吗?
  • 扫描识别控件Dynamic Web TWAIN v12.2发布,改进SSL证书
  • 微信开放平台全网发布【失败】的几点排查方法
  • 运行时添加log4j2的appender
  • [Shell 脚本] 备份网站文件至OSS服务(纯shell脚本无sdk) ...
  • gunicorn工作原理
  • kubernetes资源对象--ingress
  • 完善智慧办公建设,小熊U租获京东数千万元A+轮融资 ...
  • ​第20课 在Android Native开发中加入新的C++类
  • # 睡眠3秒_床上这样睡觉的人,睡眠质量多半不好
  • #QT(一种朴素的计算器实现方法)
  • (003)SlickEdit Unity的补全
  • (6)设计一个TimeMap
  • (ctrl.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“
  • (c语言)strcpy函数用法
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第5节(封闭类和Final方法)
  • (LeetCode) T14. Longest Common Prefix
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (十) 初识 Docker file
  • (四)docker:为mysql和java jar运行环境创建同一网络,容器互联
  • (一)80c52学习之旅-起始篇
  • (转)编辑寄语:因为爱心,所以美丽
  • (转)程序员技术练级攻略
  • .helper勒索病毒的最新威胁:如何恢复您的数据?
  • .NET LINQ 通常分 Syntax Query 和Syntax Method
  • .NET3.5下用Lambda简化跨线程访问窗体控件,避免繁复的delegate,Invoke(转)