更新您的密碼

Spring Security
Remote
1
08:31 PM · Nov 29 ,2025

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">密碼不匹配</span>
                    
   <button type="submit" onclick="savePass()">修改密碼</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 Tests

最後,讓我們使用 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("[email protected]");
        if (user == null) {
            user = new User();
            user.setFirstName("Test");
            user.setLastName("Test");
            user.setPassword(passwordEncoder.encode("test"));
            user.setEmail("[email protected]");
            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("[email protected]", "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("[email protected]", "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. 結論

這就是一個簡單的實現方式,允許用户在註冊並登錄應用程序後更改自己的密碼。

下一條 »
通知用户從新設備或位置登錄
« 之前的
註冊 – 密碼強度和規則
user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.