SpringBoot 后台服务端 杂记

由于公司人手不足,导致桌面应用、微信小程序以及两端对应的服务端都由我自己开发。

为了加快开发进度,采用 SpringBoot + SpringSecurity + JWT的方式(桌面应用的服务端,微信小程序服务端的身份验证并没有使用 SpringSecurity ,使用 JWT + 拦截器)。

相对遇到一些比较杂乱的问题,这里记下来用来供以后查询使用。

1、最开始使用 SpringSecrity 的时候,一种是WebFlux 模式,一直是 Web 模式。因为听说 WebFlux 各种好处(降低CPU等一堆我并没有感觉出来的好处),加上想挺说 WebFlux 模式,就采用了 WebFlux 模式构建服务端,用上我就有点后悔了

刚开始接触 SpringSecrity 的配置方式(这里说的是 Web 模式的配置),感觉还挺简单。但是用到 WebFlux 上还是有很大的不一样的。

WebFlux 模式下大部分都是用了链式编程,之前仅仅是听说过并没有真正的使用过链式编程:

 1 String password = authentication.getCredentials().toString();
 2         Mono<UserDetails> mono = this.retrieveUser(authentication.getPrincipal().toString());
 3         return mono.publishOn(scheduler)
 4                 .filter(u -> passwordEncoder.matches(password,u.getPassword()))
 5                 .switchIfEmpty(Mono.defer(() -> Mono.error(new BadCredentialsException("账号或密码错误!"))))
 6                 .flatMap(u -> {
 7                     UserEntity userEntity = ((AuthenticatedMember)u).getUserEntity();
 8                     if (userEntity.getStatus() == 0){
 9                         return Mono.error(new BadCredentialsException(userEntity.getRemark()));
10                     }
11                     boolean upgradeEncoding = userService != null && passwordEncoder.upgradeEncoding(u.getPassword());
12                     if (upgradeEncoding) {
13                         String newPassword = passwordEncoder.encode(password);
14                         return userService.updatePassword(u, newPassword);
15                     } else {
16                         return Mono.just(u);
17                     }
18                 })
19                 .flatMap(userDetails -> Mono.just(userDetails))
20                 .map(u -> new AuthenticationToken(u, u.getPassword(), password, u.getAuthorities()));

而且其中的Mono类这是啥玩意,之前都没有用过,最开始把这段调通心态都要崩了。

2、SpringSecrity 调整完成之后,就开始了业务代码的编写。突然有一天跟我说要做微信小程序,让我把原来的服务端加上微信小程序的内容,当时内心是崩溃的。

其实现在回想起来用 SpringSecrity 进行身份认证也没有啥问题,但是当时没有在 SpringBoot 用过拦截器,所以就好奇了一下下,发现用 SpringBoot 的拦截器确实上手要比 SpringSecrity 快上很多。

既然微信小程序的访问路径都已经使用拦截器了,那我就合计把 SpringSecrity 的 SecurityConfig 设置成免验证的路径吧。但是万万没想到竟然出问题了!

一开始不知道免验证路径也是要经过 SpringSecrity 的 ServerSecurityContextRepository.load() 函数的,就是各种打断点,各种测试最后发现他竟然也要走一遍这个函数。

3、最开始使用 JWT 并不知道这玩意有长度的限制,最开始把整个实体都转成 Map 然后存在 JWT 中,就是毫不客气的各种报错!最后发现应该是实体转的 Map 长度太长了,存不进去,之后就修改仅存一个ID了。

目前想起来的就是这些,之后如果有继续补充

posted @ 2022-10-09 13:54  拾柒年  阅读(161)  评论(0编辑  收藏  举报