{fbmip:fixed type="top" id="mipfixed" dataSlide="header-fixed-slide" class="fb-header-fixed"}
{fbview:mainmenu menuItemCode='$menuItemCode'/}
{/fbmip:fixed}
{fbmip:img fit='cover' src="$banner2['img_url']" alt="$banner2['title']"/}

在Spring开发中使用邮件进行用户注册验证(2)

  • 发布时间:
  • 浏览:194
  • 来源:平步科技官网

书接上文,继续讲解在Spring中使用邮件进行用户注册验证

4.将帐户激活检查添加到登录过程

我们需要添加代码来检查用户是否已启用:

我们在例4.1中看到这一点。它显示了MyUserDetailsS​​ervice的loadUserByUsername方法

@Autowired

UserRepository userRepository;

 

public UserDetails loadUserByUsername(String email) 

  throws UsernameNotFoundException {

  

    boolean enabled = true;

    boolean accountNonExpired = true;

    boolean credentialsNonExpired = true;

    boolean accountNonLocked = true;

    try {

        User user = userRepository.findByEmail(email);

        if (user == null) {

            throw new UsernameNotFoundException(

              "No user found with username: " + email);

        }

         

        return new org.springframework.security.core.userdetails.User(

          user.getEmail(), 

          user.getPassword().toLowerCase(), 

          user.isEnabled(), 

          accountNonExpired, 

          credentialsNonExpired, 

          accountNonLocked, 

          getAuthorities(user.getRole()));

    } catch (Exception e) {

        throw new RuntimeException(e);

    }

}

我们可以看到,现在MyUserDetailsS​​ervice不使用用户的enabled标志 - 因此它只允许用户进行身份验证。

现在,我们将添加一个AuthenticationFailureHandler来自定义来自MyUserDetailsS​​ervice的异常消息。我们的CustomAuthenticationFailureHandler如例4.2所示。:

例4.2。- CustomAuthenticationFailureHandler:

@Component

public class CustomAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {

 

    @Autowired

    private MessageSource messages;

 

    @Autowired

    private LocaleResolver localeResolver;

 

    @Override

    public void onAuthenticationFailure(HttpServletRequest request, 

      HttpServletResponse response, AuthenticationException exception)

      throws IOException, ServletException {

        setDefaultFailureUrl("/login.html?error=true");

 

        super.onAuthenticationFailure(request, response, exception);

 

        Locale locale = localeResolver.resolveLocale(request);

 

        String errorMessage = messages.getMessage("message.badCredentials", null, locale);

 

        if (exception.getMessage().equalsIgnoreCase("User is disabled")) {

            errorMessage = messages.getMessage("auth.message.disabled", null, locale);

        } else if (exception.getMessage().equalsIgnoreCase("User account has expired")) {

            errorMessage = messages.getMessage("auth.message.expired", null, locale);

        }

 

        request.getSession().setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, errorMessage);

    }

}

我们需要修改login.html以显示错误消息。

例4.3。- 在login.html上显示错误消息:

<div th:if="${param.error != null}"

  th:text="${session[SPRING_SECURITY_LAST_EXCEPTION]}">error</div>

5.调整持久层

现在让我们提供一些涉及验证令牌和用户的操作的实际实现。

我们将涵盖:

一个新的VerificationTokenRepository

需要IUserInterface中的新方法及其对新CRUD操作的实现

例5.1 - 5.3。显示新的接口和实现:

例5.1。- VerificationTokenRepository

public interface VerificationTokenRepository 

  extends JpaRepository<VerificationToken, Long> {

 

    VerificationToken findByToken(String token);

 

    VerificationToken findByUser(User user);

}

例5.2。- IUserService接口

public interface IUserService {

     

    User registerNewUserAccount(UserDto accountDto) 

      throws EmailExistsException;

 

    User getUser(String verificationToken);

 

    void saveRegisteredUser(User user);

 

    void createVerificationToken(User user, String token);

 

    VerificationToken getVerificationToken(String VerificationToken);

}

例5.3。该UserService

@Service

@Transactional

public class UserService implements IUserService {

    @Autowired

    private UserRepository repository;

 

    @Autowired

    private VerificationTokenRepository tokenRepository;

 

    @Override

    public User registerNewUserAccount(UserDto accountDto) 

      throws EmailExistsException {

         

        if (emailExist(accountDto.getEmail())) {

            throw new EmailExistsException(

              "There is an account with that email adress: "

              + accountDto.getEmail());

        }

         

        User user = new User();

        user.setFirstName(accountDto.getFirstName());

        user.setLastName(accountDto.getLastName());

        user.setPassword(accountDto.getPassword());

        user.setEmail(accountDto.getEmail());

        user.setRole(new Role(Integer.valueOf(1), user));

        return repository.save(user);

    }

 

    private boolean emailExist(String email) {

        User user = repository.findByEmail(email);

        if (user != null) {

            return true;

        }

        return false;

    }

     

    @Override

    public User getUser(String verificationToken) {

        User user = tokenRepository.findByToken(verificationToken).getUser();

        return user;

    }

     

    @Override

    public VerificationToken getVerificationToken(String VerificationToken) {

        return tokenRepository.findByToken(VerificationToken);

    }

     

    @Override

    public void saveRegisteredUser(User user) {

        repository.save(user);

    }

     

    @Override

    public void createVerificationToken(User user, String token) {

        VerificationToken myToken = new VerificationToken(token, user);

        tokenRepository.save(myToken);

    }

}

六,结论

在本文中,我们扩展了注册流程,以包含基于电子邮件的帐户激活程序。

帐户激活逻辑需要通过电子邮件向用户发送验证令牌,以便他们可以将其发送回控制器以验证其身份。

这个注册与Spring Security教程的实现可以在GitHub项目中找到- 这是一个基于Eclipse的项目,因此它应该很容易导入和运行。