清晰搞懂Spring Security的登录认证( 三 )

2、yml配置文件 。配置数据库的基本连接信息 。
# 指定端口号server:port: 8080# 配置数据源spring:Application:name: security# 数据库连接池配置datasource:druid:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/db_security?useUnicode=true&characterEncoding=utf-8&useSSL=falseusername: rootpassword: 123456# Redis配置redis: # 这是我的虚拟机IP host: 192.168.150.100port: 6379password: 123456# 操作0号数据库,默认有16个数据库database: 0jedis:pool:max-active: 8 # 最大连接数max-wait: 1ms # 连接池最大阻塞等待时间max-idle: 4# 连接池中的最大空闲连接min-idle: 0# 连接池中的最小空闲连接cache:redis:time-to-live: 1800000 # 设置数据过期时间为半小时(ms)3、实体类 。因为数据库只有一个表,因此我们只需要与之对应上就可以了 。
@Data@AllArgsConstructor@NoArgsConstructor@TableName(value = https://www.isolves.com/it/cxkf/kj/2022-07-21/"sys_user")@ToStringpublic class User implements Serializable {private static final long serialVersionUID = 1L;/** 主键 */@TableIdprivate Long id;/** 用户名 */private String userName;/** 昵称 */private String nickName;/** 密码 */private String password;/** 账号状态(0正常 1停用) */private String status;/** 邮箱 */private String email;/** 手机号 */private String phonenumber;/** 用户性别(0男,1女,2未知) */private String sex;/** 头像 */private String avatar;/** 用户类型(0管理员,1普通用户) */private String userType;/** 创建人的用户id */private Long createBy;/*** 创建时间*/private Date createTime;/** * 更新人 */private Long updateBy;/** * 更新时间 */private Date updateTime;/** 删除标志(0代表未删除,1代表已删除) */private Integer delFlag;}4、mapper编写 。因为这里使用的是MP,所以我们直接继承BaseMapper就搞定了 。
@Repositorypublic interface UserMapper extends BaseMapper<User> { }5、service编写 。分别编写接口和实现类的代码,这里还是MP的常规操作 。
public interface UserService extends IService<User> { }------ 下面的在 impl 包里面 ------@Servicepublic class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService { }6、controller编写 。这里主要就是UserController和一个简单的hello接口用作后续测试使用 。
@RestControllerpublic class HelloController {@GetMapping("/hello")public String hello() {return "Hello";}}--- 两个不一样的文件 ---@RestController@RequestMapping("/user")@Slf4jpublic class UserController {@Autowiredprivate UserService loginService;@PostMapping("/login")public Result login(@RequestBody User user){log.info("登录的用户为{}", user);return loginService.login(user);}}3.1.3、工具类、部分配置类1、Redis配置类 。主要是对Redis默认的序列化器进行一个更换 。
@Configurationpublic class RedisConfig {@Bean@SuppressWarnings(value = https://www.isolves.com/it/cxkf/kj/2022-07-21/{"unchecked", "rawtypes" })public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory){RedisTemplate template = new RedisTemplate<>();template.setConnectionFactory(connectionFactory);FastJsonRedisSerializer serializer = new FastJsonRedisSerializer(Object.class);// 使用StringRedisSerializer来序列化和反序列化redis的key值template.setKeySerializer(new StringRedisSerializer());template.setValueSerializer(serializer);// Hash的key也采用StringRedisSerializer的序列化方式template.setHashKeySerializer(new StringRedisSerializer());template.setHashValueSerializer(serializer);template.afterPropertiesSet();return template;}}2、JWT工具类 。这里就不过多的介绍啦,有兴趣的可以读一下 。需要注意的就是自己更换密钥的时候,因为用到的是 Base64.getDecoder() ,只允许A~Z、 a~z、 0~9这些字符,如果需要用到特殊字符的话则需要换成 Base64.getMimeDecoder()  。(Ctrl+F 搜一下就知道在哪啦)
public class JwtUtil {// 设置有效期为60 * 60 *1000一个小时public static final Long JWT_TTL = 60 * 60 * 1000L;//设置秘钥明文public static final String JWT_KEY = "xbaozi";public static String getUUID() {String token = UUID.randomUUID().toString().replaceAll("-", "");return token;}/*** 生成jtw* @param subject token中要存放的数据(json格式)*/public static String createJWT(String subject) {JwtBuilder builder = getJwtBuilder(subject, null, getUUID());// 设置过期时间return builder.compact();}/*** 生成jwt* @param subjecttoken中要存放的数据(json格式)* @param ttlMillis token超时时间*/public static String createJWT(String subject, Long ttlMillis) {JwtBuilder builder = getJwtBuilder(subject, ttlMillis, getUUID());// 设置过期时间return builder.compact();}private static JwtBuilder getJwtBuilder(String subject, Long ttlMillis, String uuid) {SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;SecretKey secretKey = generalKey();long nowMillis = System.currentTimeMillis();Date now = new Date(nowMillis);if (ttlMillis == null) {ttlMillis = JwtUtil.JWT_TTL;}long expMillis = nowMillis + ttlMillis;Date expDate = new Date(expMillis);return Jwts.builder().setId(uuid)//唯一的ID.setSubject(subject)// 主题可以是JSON数据.setIssuer("sg")// 签发者.setIssuedAt(now)// 签发时间.signWith(signatureAlgorithm, secretKey) //使用HS256对称加密算法签名, 第二个参数为秘钥.setExpiration(expDate);}/*** 创建token*/public static String createJWT(String id, String subject, Long ttlMillis) {JwtBuilder builder = getJwtBuilder(subject, ttlMillis, id);// 设置过期时间return builder.compact();}/*** 生成加密后的秘钥 secretKey*/public static SecretKey generalKey() {byte[] encodedKey = Base64.getDecoder().decode(JwtUtil.JWT_KEY);SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");return key;}/*** 解析* @throws Exception*/public static Claims parseJWT(String jwt) throws Exception {SecretKey secretKey = generalKey();return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(jwt).getBody();}}


推荐阅读