Spring Security Registration - Bestätigungsmail erneut senden

Spring Security Registration - Bestätigungs-E-Mail erneut senden

1. Überblick

In diesem Tutorial setzen wir die laufendenRegistration with Spring Security series fort, um den Bestätigungslink erneut an den Benutzer zu senden, falls dieser abläuft, bevor er die Möglichkeit hat, sein Konto zu aktivieren.

Lassen Sie uns zunächst sehen, was passiert, wenn der Benutzerrequests another verification link abläuft, falls der vorherige abgelaufen ist.

Erstens: Wir setzen das vorhandene Token mit einem neuenexpireDatezurück. Wir senden dem Benutzer eine neue E-Mail mit dem neuen Link / Token:

@RequestMapping(value = "/user/resendRegistrationToken", method = RequestMethod.GET)
@ResponseBody
public GenericResponse resendRegistrationToken(
  HttpServletRequest request, @RequestParam("token") String existingToken) {
    VerificationToken newToken = userService.generateNewVerificationToken(existingToken);

    User user = userService.getUser(newToken.getToken());
    String appUrl =
      "http://" + request.getServerName() +
      ":" + request.getServerPort() +
      request.getContextPath();
    SimpleMailMessage email =
      constructResendVerificationTokenEmail(appUrl, request.getLocale(), newToken, user);
    mailSender.send(email);

    return new GenericResponse(
      messages.getMessage("message.resendToken", null, request.getLocale()));
}

Und das Dienstprogramm zum Erstellen der E-Mail-Nachricht, die der Benutzer erhält -constructResendVerificationTokenEmail():

private SimpleMailMessage constructResendVerificationTokenEmail
  (String contextPath, Locale locale, VerificationToken newToken, User user) {
    String confirmationUrl =
      contextPath + "/regitrationConfirm.html?token=" + newToken.getToken();
    String message = messages.getMessage("message.resendToken", null, locale);
    SimpleMailMessage email = new SimpleMailMessage();
    email.setSubject("Resend Registration Token");
    email.setText(message + " rn" + confirmationUrl);
    email.setFrom(env.getProperty("support.email"));
    email.setTo(user.getEmail());
    return email;
}

Wir müssen auch die vorhandene Registrierungsfunktion ändern - indem wir einige neue Informationen zum Modellabout the expiration of the tokenhinzufügen:

@RequestMapping(value = "/regitrationConfirm", method = RequestMethod.GET)
public String confirmRegistration(
  Locale locale, Model model, @RequestParam("token") String token) {
    VerificationToken verificationToken = userService.getVerificationToken(token);
    if (verificationToken == null) {
        String message = messages.getMessage("auth.message.invalidToken", null, locale);
        model.addAttribute("message", message);
        return "redirect:/badUser.html?lang=" + locale.getLanguage();
    }

    User user = verificationToken.getUser();
    Calendar cal = Calendar.getInstance();
    if ((verificationToken.getExpiryDate().getTime() - cal.getTime().getTime()) <= 0) {
        model.addAttribute("message", messages.getMessage("auth.message.expired", null, locale));
        model.addAttribute("expired", true);
        model.addAttribute("token", token);
        return "redirect:/badUser.html?lang=" + locale.getLanguage();
    }

    user.setEnabled(true);
    userService.saveRegisteredUser(user);
    model.addAttribute("message", messages.getMessage("message.accountVerified", null, locale));
    return "redirect:/login.html?lang=" + locale.getLanguage();
}

3. Ausnahmehandler

Die vorherige Funktionalität besteht unter bestimmten Bedingungen darin, Ausnahmen auszulösen. Diese Ausnahmen müssen behandelt werden, und wir werden dies mita custom exception handler tun:

@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {

    @Autowired
    private MessageSource messages;

    @ExceptionHandler({ UserNotFoundException.class })
    public ResponseEntity handleUserNotFound(RuntimeException ex, WebRequest request) {
        logger.error("404 Status Code", ex);
        GenericResponse bodyOfResponse = new GenericResponse(
          messages.getMessage("message.userNotFound", null, request.getLocale()), "UserNotFound");

        return handleExceptionInternal(
          ex, bodyOfResponse, new HttpHeaders(), HttpStatus.NOT_FOUND, request);
    }

    @ExceptionHandler({ MailAuthenticationException.class })
    public ResponseEntity handleMail(RuntimeException ex, WebRequest request) {
        logger.error("500 Status Code", ex);
        GenericResponse bodyOfResponse = new GenericResponse(
          messages.getMessage(
            "message.email.config.error", null, request.getLocale()), "MailError");

        return handleExceptionInternal(
          ex, bodyOfResponse, new HttpHeaders(), HttpStatus.NOT_FOUND, request);
    }

    @ExceptionHandler({ Exception.class })
    public ResponseEntity handleInternal(RuntimeException ex, WebRequest request) {
        logger.error("500 Status Code", ex);
        GenericResponse bodyOfResponse = new GenericResponse(
          messages.getMessage(
            "message.error", null, request.getLocale()), "InternalError");

        return handleExceptionInternal(
          ex, bodyOfResponse, new HttpHeaders(), HttpStatus.NOT_FOUND, request);
    }
}


Beachten Sie, dass:

  • Wir haben die Annotation@ControllerAdviceverwendet, um Ausnahmen in der gesamten Anwendung zu behandeln

  • Wir haben ein einfaches ObjektGenericResponse verwendet, um die Antwort zu senden:

public class GenericResponse {
    private String message;
    private String error;

    public GenericResponse(String message) {
        super();
        this.message = message;
    }

    public GenericResponse(String message, String error) {
        super();
        this.message = message;
        this.error = error;
    }
}

4. Ändern SiebadUser.html

Wir werden jetztbadUser.html ändern, indem wir dem Benutzer ermöglichen, nur dann neueVerificationToken zu erhalten, wenn ihr Token abgelaufen ist:



bad user


error


signup

resend

Beachten Sie, dass wir hier ein sehr einfaches Javascript und JQuery verwendet haben, um die Antwort von "/ user / resendRegistrationToken" zu verarbeiten und den Benutzer basierend darauf umzuleiten.

5. Fazit

In diesem kurzen Artikel haben wir dem Benutzerrequest a new verification link to activate their account erlaubt, falls der alte abgelaufen ist.

Diefull implementation dieses Tutorials finden Sie inthe github project - dies ist ein Eclipse-basiertes Projekt, daher sollte es einfach zu importieren und auszuführen sein.