Segue um exemplo simples feito em Thymeleaf, mas em Vue não mudaria mta coisa:
O primeiro passo seria mapear as entidades para User e Authority ( vou omitir gets/sets):
@Entity
@Table(name = "users")
public class User {
@Id
@NotBlank
private String username;
@NotBlank
private String password;
private Boolean enabled;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "user", fetch = FetchType.LAZY)
private List<Pedido> pedidos;
@ElementCollection
@CollectionTable(name = "authorities", joinColumns = @JoinColumn(name = "username"))
private Set<Authority> authorities = new HashSet<>();
}
@Embeddable
public class Authority {
private String authority;
public Authority() {
}
public Authority(String authority) {
this.authority = authority;
}
}
Então cria-se um Controller para gerenciar a tela e salvar o registro:
@Controller
public class CadastroUsuarioController {
@Autowired
private UserRepository repository;
@GetMapping("/cadastrar")
public ModelAndView login() {
ModelAndView mv = new ModelAndView("cadastrar");
mv.addObject("user", new User());
return mv;
}
@PostMapping("/cadastrar")
public String cadastrar(@Valid User user, BindingResult result) {
if (result.hasErrors()) {
return "cadastrar";
}
user.setPassword(new BCryptPasswordEncoder().encode(user.getPassword()));
user.setEnabled(true);
user.addAuthority("USER");
repository.save(user);
return "redirect:/login";
}
}
Cria uma tela para cadastro:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{base :: head}"></head>
<body>
<div th:replace="~{base :: logo}"></div>
<div class="container">
<div th:replace="~{base :: titulo('Novo Usuário')}"></div>
<div class="card mb-3">
<form th:object="${user}" th:action="@{/cadastrar}" class="card-body" method="post">
<div class="form-group">
<label for="username">Usuário</label>
<input th:field="*{username}" th:errorClass="is-invalid" class="form-control" placeholder="usuário" />
<div class="invalid-feedback" th:errors="*{username}"></div>
</div>
<div class="form-group">
<label for="password">Senha</label>
<input type="password" th:field="*{password}" th:errorClass="is-invalid" class="form-control" placeholder="senha" />
<div class="invalid-feedback" th:errors="*{password}"></div>
</div>
<button class="btn btn-primary" type="submit">Cadastrar</button>
</form>
</div>
</div>
</body>
</html>
e por fim, adiciona permissão para a tela de cadastro
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/cadastrar").permitAll()
.antMatchers("/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin(form ->
form.loginPage("/login")
.permitAll()
.defaultSuccessUrl("/usuario/pedido", true)
)
.logout(logout -> logout.logoutUrl("/logout").logoutSuccessUrl("/home"))
.csrf().disable();
}
Basicamente é isso, poderia fazer umas melhorias como criar um DTO para receber os dados do usuário, validar se o usuário já está cadastrado, criar a tela usando vue (dai teria que adaptar controller para um @RestController) mas no geral é isso.
Um pena não ter adicionado uma aula com isso, teria acrescido bastante ao curso.