依赖引入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-jsqlparser-4.9</artifactId>
<version>3.5.10.1</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.10.1</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter-test</artifactId>
<version>3.5.10.1</version>
</dependency>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-boot-starter</artifactId>
<version>1.5.2</version>
</dependency>
</dependencies>

编写数据表实体类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@NoArgsConstructor
@AllArgsConstructor
@Data
public class User {
@TableId(type = IdType.ASSIGN_ID)
private Long id;
private String name;
@NotBlank
@Email
private String email;
@NotBlank
private String password;
private String persona;
private String enabled;
private String avatar;
private LocalDateTime createTime;
}

编写 UserDetails 的实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserLogin implements UserDetails {
private User user;

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return List.of(new SimpleGrantedAuthority("ROLE_" + user.getPersona()));
}

@Override
public String getPassword() {
return user.getPassword();
}

@Override
public String getUsername() {
// 使用邮箱登录
return user.getEmail();
}

@Override
public boolean isAccountNonExpired() {
return UserDetails.super.isAccountNonExpired();
}

@Override
public boolean isAccountNonLocked() {
return UserDetails.super.isAccountNonLocked();
}

@Override
public boolean isCredentialsNonExpired() {
return UserDetails.super.isCredentialsNonExpired();
}

@Override
public boolean isEnabled() {
// 使用1表示启用,0表示禁用
return "1".equals(user.getEnabled());
}
}

编写 UserMapper 接口

1
2
3
@Mapper
public interface UserMapper extends MPJBaseMapper<User> {
}

编写 UserDetailsService 的实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Resource
private UserMapper userMapper;

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//查询用户信息
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(User::getEmail, username);
User user = userMapper.selectOne(queryWrapper);
//如果没有查询到用户,就抛出异常
if (Objects.isNull(user)) {
throw new BadCredentialsException("用户名或者密码错误!");
}
//将数据封装成UserDetails
return new UserLogin(user);
}

}

编写自定义控制器

1
2
3
4
5
6
7
8
9
10
11
@RestController
@RequestMapping("/user")
public class UserController {
@Resource
private IUserService userService;

@PostMapping("/login")
public Map<String, String> login(@RequestBody @Validated User user) {
return userService.login(user);
}
}

编写 userServiceImpl 实现类

1
2
3
4
5
6
7
8
9
10
11
12
public Map<String, String> login(User user) {
// 进行用户认证,用邮箱作为用户名登陆
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getEmail(), user.getPassword());
Authentication authenticate = authenticationManager.authenticate(authenticationToken);
//通过了,生成jwt
UserLogin loginUser = (UserLogin) authenticate.getPrincipal();
// 可以选择存放在redis ......
Map<String, String> map = new HashMap<>();
// 将token返回给前端
map.put("token", token);
return map;
}