Используя весеннюю загрузку, Java и спящий режим.
Проще говоря, я могу подтвердить пользователя, отправить электронное письмо с подтверждением, и когда пользователь перейдет по ссылке, они будут отправлены по электронной почте. Он переводит их на страницу подтверждения. На этой странице они перенаправляются в зависимости от того, вошли они в систему или нет, и были ли они проверены ранее или нет.
Каждый экземпляр, токен должен быть удален. Я не знаю, что я делаю неправильно в коде.
Это VerifyController
import com.blah.app.models.Alert;
import com.blah.app.models.AlertType;
import com.blah.app.models.entities.User;
import com.blah.app.models.entities.VerificationToken;
import com.blah.app.repositories.UserRepository;
import com.blah.app.repositories.VerificationTokenRepository;
import java.util.Base64;
import java.util.Collections;
import java.util.Optional;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
@AllArgsConstructor
@Controller
@Slf4j
@RequestMapping("/user-verification")
public class VerificationController {
private final MessageSource messageSource;
private final HttpServletRequest request;
private final VerificationTokenRepository verificationTokenRepository;
private final UserRepository userRepository;
@GetMapping
public String verificationRedirect(@RequestParam("token") String token,
RedirectAttributes redirectAttributes) {
Base64.Decoder decoder = Base64.getDecoder();
UUID uuidToken = UUID.fromString(new String(decoder.decode(token)));
Optional<VerificationToken> optionalVerificationToken =
this.verificationTokenRepository.findByToken(uuidToken);
if (optionalVerificationToken.isPresent()) {
VerificationToken verificationToken = optionalVerificationToken.get();
User user = verificationToken.getUser();
if (user.isEnabled() == true) {
//user enabled
if (request.getUserPrincipal() != null) {
//user signed in and enable
this.verificationTokenRepository.delete(verificationToken);
Alert alert = Alert.builder()
.type(AlertType.WARNING)
.message(this.messageSource
.getMessage("messages.verifiedAlready", null,
LocaleContextHolder.getLocale()))
.closable(true)
.build();
redirectAttributes.addFlashAttribute("alerts", Collections.singletonList(alert));
this.verificationTokenRepository.delete(verificationToken);
return "redirect:app";
} else {
//user signed out and enabled
this.verificationTokenRepository.delete(verificationToken);
Alert alert = Alert.builder()
.type(AlertType.WARNING)
.message(this.messageSource
.getMessage("messages.verifiedAlreadySignedOut", null,
LocaleContextHolder.getLocale()))
.closable(true)
.build();
redirectAttributes.addFlashAttribute("alerts", Collections.singletonList(alert));
return "redirect:sign-in";
}
} else {
//user not enabled
if (request.getUserPrincipal() != null) {
//user is signed in
// FIXME: needs to redirect to app
user.setEnabled(true);
this.verificationTokenRepository.delete(verificationToken);
Alert alert = Alert.builder()
.type(AlertType.SUCCESS)
.message(this.messageSource
.getMessage("messages.verificationSuccess", null,
LocaleContextHolder.getLocale()))
.closable(true)
.build();
redirectAttributes.addFlashAttribute("alerts", Collections.singletonList(alert));
return "redirect:app";
} else {
//uesr not signed in
user.setEnabled(true);
this.verificationTokenRepository.delete(verificationToken);
Alert alert = Alert.builder()
.type(AlertType.SUCCESS)
.message(this.messageSource
.getMessage("messages.verificationSuccessSignedOut", null,
LocaleContextHolder.getLocale()))
.closable(true)
.build();
redirectAttributes.addFlashAttribute("alerts", Collections.singletonList(alert));
return "redirect:sign-in";
}
}
}
Alert alert = Alert.builder()
.type(AlertType.WARNING)
.message(this.messageSource
.getMessage("messages.verifiedInvalidToken", null, LocaleContextHolder.getLocale()))
.closable(true)
.build();
redirectAttributes.addFlashAttribute("alerts", Collections.singletonList(alert));
return "redirect:sign-in";
}
}
User entity
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Transient;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Entity
@Table(name = "user_account")
public class User extends BaseEntity {
@Column(columnDefinition = "text")
private String forename;
@Column(columnDefinition = "text")
private String surname;
@Column(nullable = false, columnDefinition = "text", unique=true)
private String email;
@Transient
private String password;
@Transient
private String confirmPassword;
@Column(nullable = false, length = 60)
private String passwordHash;
@Column(name = "enabled")
private boolean enabled;
public User() {
super();
this.enabled=false;
}
@OneToMany(mappedBy = "user", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<UserRole> roles;
@OneToOne(cascade=CascadeType.ALL, mappedBy="user")
private VerificationToken verificationToken;
};
объект токена проверки
import java.util.UUID;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Getter
@Entity
@Setter
@Table(name = "user_verification_token")
public class VerificationToken extends BaseEntity {
@Column(updatable = false, nullable = false)
private UUID token;
@OneToOne(optional = false)
private User user;
}