Перейти к основному содержимому

Обновление вашего пароля

· 3 мин. чтения

1. Обзор

В этой быстрой статье мы реализуем простую функцию «Изменить мой собственный пароль», доступную пользователю после регистрации и входа в систему.

2. Клиентская сторона — страница смены пароля

Давайте взглянем на очень простую клиентскую страницу:

<html>
<body>
<div id="errormsg" style="display:none"></div>
<div>
<input id="oldpass" name="oldpassword" type="password" />
<input id="pass" name="password" type="password" />
<input id="passConfirm" type="password" />
<span id="error" style="display:none">Password mismatch</span>

<button type="submit" onclick="savePass()">Change Password</button>
</div>

<script src="jquery.min.js"></script>
<script type="text/javascript">

var serverContext = [[@{/}]];
function savePass(){
var pass = $("#pass").val();
var valid = pass == $("#passConfirm").val();
if(!valid) {
$("#error").show();
return;
}
$.post(serverContext + "user/updatePassword",
{password: pass, oldpassword: $("#oldpass").val()} ,function(data){
window.location.href = serverContext +"/home.html?message="+data.message;
})
.fail(function(data) {
$("#errormsg").show().html(data.responseJSON.message);
});
}
</script>
</body>
</html>

3. Обновите пароль пользователя

Теперь давайте также реализуем операцию на стороне сервера:

@PostMapping("/user/updatePassword")
@PreAuthorize("hasRole('READ_PRIVILEGE')")
public GenericResponse changeUserPassword(Locale locale,
@RequestParam("password") String password,
@RequestParam("oldpassword") String oldPassword) {
User user = userService.findUserByEmail(
SecurityContextHolder.getContext().getAuthentication().getName());

if (!userService.checkIfValidOldPassword(user, oldPassword)) {
throw new InvalidOldPasswordException();
}
userService.changeUserPassword(user, password);
return new GenericResponse(messages.getMessage("message.updatePasswordSuc", null, locale));
}

Обратите внимание, как этот метод защищен аннотацией @PreAuthorize , поскольку он должен быть доступен только зарегистрированным пользователям .

4. Тесты API

Наконец, давайте используем API с некоторыми тестами API, чтобы убедиться, что все работает нормально; мы начнем с простой настройки теста и инициализации данных:

@ExtendWith(SpringExtension.class)
@ContextConfiguration(
classes = { ConfigTest.class, PersistenceJPAConfig.class },
loader = AnnotationConfigContextLoader.class)
public class ChangePasswordApiTest {
private final String URL_PREFIX = "http://localhost:8080/";
private final String URL = URL_PREFIX + "/user/updatePassword";

@Autowired
private UserRepository userRepository;

@Autowired
private PasswordEncoder passwordEncoder;

FormAuthConfig formConfig = new FormAuthConfig(
URL_PREFIX + "/login", "username", "password");

@BeforeEach
public void init() {
User user = userRepository.findByEmail("test@test.com");
if (user == null) {
user = new User();
user.setFirstName("Test");
user.setLastName("Test");
user.setPassword(passwordEncoder.encode("test"));
user.setEmail("test@test.com");
user.setEnabled(true);
userRepository.save(user);
} else {
user.setPassword(passwordEncoder.encode("test"));
userRepository.save(user);
}
}
}

Теперь давайте попробуем изменить пароль для зарегистрированного пользователя :

@Test
public void givenLoggedInUser_whenChangingPassword_thenCorrect() {
RequestSpecification request = RestAssured.given().auth()
.form("test@test.com", "test", formConfig);

Map<String, String> params = new HashMap<String, String>();
params.put("oldpassword", "test");
params.put("password", "newtest");

Response response = request.with().params(params).post(URL);

assertEquals(200, response.statusCode());
assertTrue(response.body().asString().contains("Password updated successfully"));
}

Далее — давайте попробуем изменить пароль , учитывая неверный старый пароль :

@Test
public void givenWrongOldPassword_whenChangingPassword_thenBadRequest() {
RequestSpecification request = RestAssured.given().auth()
.form("test@test.com", "test", formConfig);

Map<String, String> params = new HashMap<String, String>();
params.put("oldpassword", "abc");
params.put("password", "newtest");

Response response = request.with().params(params).post(URL);

assertEquals(400, response.statusCode());
assertTrue(response.body().asString().contains("Invalid Old Password"));
}

Наконец — попробуем сменить пароль без аутентификации :

@Test
public void givenNotAuthenticatedUser_whenChangingPassword_thenRedirect() {
Map<String, String> params = new HashMap<String, String>();
params.put("oldpassword", "abc");
params.put("password", "xyz");

Response response = RestAssured.with().params(params).post(URL);

assertEquals(302, response.statusCode());
assertFalse(response.body().asString().contains("Password updated successfully"));
}

Обратите внимание, как — для каждого теста — мы предоставляем FormAuthConfig для обработки аутентификации.

Мы также сбрасываем пароль через init() , чтобы убедиться, что мы используем правильный пароль перед тестом.

5. Вывод

И это обертка — простой способ позволить пользователю изменить свой пароль после регистрации и входа в приложение.

Полную реализацию этого руководства можно найти в проекте github — это проект на основе Eclipse, поэтому его легко импортировать и запускать как есть.