本章结束后对应的节选代码文件:Gangbb-Vue-12-13-Login(与12章合并)
https://github.com/Gang-bb/Gangbb-Vue
历史遗留TODO:
- 第四章
- 登录日志还未实现。(到登录和权限模块完成)
LogAspect
从缓存获取当前的用户信息使用模拟的数据(到登录和权限模块完成)
- 第十一章
- 需要在Spring Security中注册的登录鉴权逻辑处理类、JWT处理的过滤器、退出登录处理类(到登录和权限模块完成)
本章将留下TODO:
- 无
本章将解决TODO:
- 第四章
- 登录日志还未实现。(到登录和权限模块完成)
LogAspect
从缓存获取当前的用户信息使用模拟的数据(到登录和权限模块完成)
- 第十一章
- 需要在Spring Security中注册的登录鉴权逻辑处理类、JWT处理的过滤器、退出登录处理类(到登录和权限模块完成)
SysDept
、SysMenu
、SysPost
、SysRole
、SysRoleDept
、SysRoleMenu
、SysUserPost
、SysUserRole
、sys_login_info
所有表都加上BaseEntity
的数据
把若依原有表中代表值字段全部换成int类型。
然后加入对应的entity、dao、service、.xml文件
与若依不同的是,我们这章还是使用之前搭建的错误返回。
新增的状态码:
SysUserDTO
该类是登录时,用户所携带的各种信息。并且实现UserDetails
接口。作用详细介绍请看第十章中的2.1
(主要的作用就是可以作为Spring Security的用户信息处理类)。在package com.gangbb.core.model.dto;
目录下。若依中叫(LoginUser
)。
UserDetailsServiceImpl
该类实现了登录的验证和鉴权的逻辑,并且实现了UserDetailsService
(在第十章的2.1中介绍到)接口,因此可注册为Spring Security处理用户登录的逻辑。在用户账号的是否删除和账号状态的判断上有所不同。
主要逻辑:
- 判断传入用户名是否为空
- 判断用户名是否存在
- 判断账号是否被停用
- 所有校验通过后,返回
SysUserDTO
用户信息类,并加上权限相关信息。
辅助的类:
UserStatus
枚举
UserConstants
中添加了用户删除的状态:
/** 用户删除 */
public static final int USER_DELETE = 1;
添加依赖
Gangbb-Vue--pom.xml
<properties>
<bitwalker.version>1.21bitwalker.version>
<jwt.version>0.9.1jwt.version>
properties>
<dependency>
<groupId>io.jsonwebtokengroupId>
<artifactId>jjwtartifactId>
<version>${jwt.version}version>
dependency>
<dependency>
<groupId>eu.bitwalkergroupId>
<artifactId>UserAgentUtilsartifactId>
<version>${bitwalker.version}version>
dependency>
Gangbb-common--pom.xml
<dependency>
<groupId>io.jsonwebtokengroupId>
<artifactId>jjwtartifactId>
dependency>
<dependency>
<groupId>eu.bitwalkergroupId>
<artifactId>UserAgentUtilsartifactId>
dependency>
添加一些工具类
id生成工具IdUtils
提供通用唯一识别码工具UUID
安全服务工具类ServletUtils
类token验证处理TokenService
:
TokenService
中使用了配置文件中声明的属性需要到Gangbb-admin下的application.yml
中配置token的相关属性:
# token配置
token:
# 令牌自定义标识
header: AUTH-TOKEN
# 令牌密钥
secret: abcdefghijklmnopqrstuvwxyz
# 令牌有效期(默认30分钟)
expireTime: 30
PS:
- 上述类中,redis调用的一些方法不一样(因为没有使用若依封装的redis工具类)。
JwtAuthenticationTokenFilter主要作用:
我们之前在国际化那一个章节中提到WebMvcConfig
这个类,它的作用是自定义实现 WebMvcConfigurer
接口类来扩展springmvc的功能。
我们效仿若依,把CorsFilter
的配置和Bean的初始化放到这个类中。(若依中该类叫ResourcesConfig
)
在package com.gangbb.core.config.WebMvcConfig
文件中加入以下配置:
/**
* 跨域过滤器配置
*/
@Bean
public CorsFilter corsFilter()
{
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
// 设置访问源地址
config.addAllowedOrigin("*");
// 设置访问源请求头
config.addAllowedHeader("*");
// 设置访问源请求方法
config.addAllowedMethod("*");
// 对接口配置跨域设置
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
LogoutSuccessHandlerImpl
主要功能:
辅助工具
修改AsyncFactory
:该工具是第四章整合日志时添加的,当时还没有recordLogininfor
增加记录登录信息 方法
新增LogUtils
:处理并记录日志文件
新建SysLoginInfoService
和其实现类SysLoginInfoServiceImpl
和数据操作层SysLoginInfoMapper
和SysLoginInfoMapper.xml
。
在SecurityConfig
中配置注入:
(二)用户权限处理相关service
SysUser
中添加判断用户是否为管理员的方法
public boolean isAdmin()
{
return isAdmin(this.id);
}
public static boolean isAdmin(Long userId)
{
return userId != null && 1L == userId;
}
根据用户ID查询权限
和根据用户ID查询菜单权限
相关的各层文件方法。新增SysUserController
,还有SysUser
各层文件的逻辑实现,功能实现与若依相同,实现方式有些区别。比如若依喜欢把逻辑写在Controller中,我比较喜欢把逻辑写在Service中。
增加新增用户接口/test/system/user/addUser
(暂时用test前缀,跳过secutity的url拦截)
新增一个用户
package com.gangbb.web.controller.system.CaptchaController
辅助操作
Gangbb-core
和Gangbb-Vue
分别加入验证码相应依赖CaptchaConfig
KaptchaTextCreator
(记得到CaptchaConfig
修改生成器的路径)Base64
application.yml
文件中加上验证码类型(gangbb.captchaType
)参照若依的登录接口定义在package com.gangbb.web.controller.monitor
的SysLoginController
新增 登录校验方法SysLoginServiceImpl
:与若依实现中有不同。(Redis工具调用、错误返回等)
登录需要修改之前的SysUserService.selectUserByUserName
,之前章节没有实现。
修改SysMenuService
,新增与若依相同的方法。
登录测试时,发现会报序列化错误。因为
sysUser
中有方法有返回值,所以在序列化时,返回的值也会被序列化存在缓存中,此时不会出错,但是从缓存中反序列化时就因为有些值没有set方法,所以会出错。
在
RedisConfig
的序列化配置中加上:om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); ``` 最后记得修改`LogAspect`中: ```java // 从缓存获取当前的用户 SysUserDTO sysUserDTO = SpringUtils.getBean(TokenService.class).getLoginUser(ServletUtils.getRequest()); ..... // 访问的用户名 sysOperationLog.setOperationName(sysUserDTO.getUsername());