欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring項(xiàng)目使用Maven和BCrypt實(shí)現(xiàn)修改密碼功能方式

 更新時(shí)間:2024年10月24日 11:52:05   作者:滌生272  
在數(shù)字時(shí)代,信息安全尤其是密碼安全至關(guān)重要,本文通過(guò)實(shí)例探討如何在Spring項(xiàng)目中利用Maven和BCrypt實(shí)現(xiàn)一個(gè)安全的密碼修改功能,我們將從環(huán)境搭建到編寫核心業(yè)務(wù)邏輯,再到完成功能測(cè)試,確保每一步都遵循最佳安全實(shí)踐,通過(guò)本文,你將了解到密碼安全的重要性

簡(jiǎn)介

在數(shù)字時(shí)代,信息安全的重要性不言而喻,尤其當(dāng)涉及到個(gè)人隱私和賬戶安全時(shí)。每天,無(wú)數(shù)的用戶登錄各種在線服務(wù),從社交媒體到銀行賬戶,再到電子郵件和云存儲(chǔ)服務(wù)。這些服務(wù)的背后,是復(fù)雜的系統(tǒng)架構(gòu),其中包含著用戶最為敏感的數(shù)據(jù)——密碼。

過(guò)去,簡(jiǎn)單的加密方法和弱密碼策略導(dǎo)致了許多嚴(yán)重的數(shù)據(jù)泄露事件。例如,2013年雅虎(Yahoo)遭遇的大規(guī)模數(shù)據(jù)泄露事件,影響了數(shù)十億的用戶賬戶,部分原因就是由于使用了不夠安全的密碼存儲(chǔ)技術(shù)。再如2016年的LinkedIn數(shù)據(jù)泄露事件,盡管該公司使用了SHA-1散列算法對(duì)密碼進(jìn)行了處理,但未加鹽的密碼散列最終還是被破解,暴露了用戶的隱私。

這些事件引發(fā)了行業(yè)對(duì)于密碼安全的深刻反思,促使開(kāi)發(fā)者和安全專家尋找更安全的解決方案。BCrypt作為一種適應(yīng)性強(qiáng)且經(jīng)過(guò)時(shí)間考驗(yàn)的密碼哈希算法,成為了現(xiàn)代密碼安全的基石。它不僅能夠有效抵御暴力破解和彩虹表攻擊,還能通過(guò)增加工作因子來(lái)適應(yīng)未來(lái)計(jì)算能力的增長(zhǎng)。

在本文中,我們將深入探討如何在Spring項(xiàng)目中利用Maven和BCrypt來(lái)實(shí)現(xiàn)一個(gè)安全的密碼修改功能。這不僅僅是關(guān)于代碼實(shí)現(xiàn)的問(wèn)題,更是一次對(duì)密碼安全重要性的重申,以及對(duì)如何在實(shí)際應(yīng)用中踐行這一原則的示范。我們將從環(huán)境搭建開(kāi)始,逐步構(gòu)建出一個(gè)既實(shí)用又安全的密碼修改流程,確保即使在最惡劣的情況下,用戶的密碼也能得到妥善保護(hù)。

通過(guò)本文的學(xué)習(xí),你將獲得寶貴的實(shí)踐經(jīng)驗(yàn),了解如何在自己的項(xiàng)目中實(shí)施類似的解決方案,從而提升應(yīng)用的安全性,給用戶提供更加安心的在線體驗(yàn)。在接下來(lái)的內(nèi)容中,我們將一步步解析實(shí)現(xiàn)過(guò)程,從添加依賴到編寫核心業(yè)務(wù)邏輯,直至完成完整的功能測(cè)試,確保每一步都遵循最佳的安全實(shí)踐。

controller(UserController)

/**
     * 修改密碼
     */
    @PutMapping("/update/pwd/{id}")
    public Result update(@PathVariable("id") long id, @RequestBody ChangePasswordVo changePasswordVo) {
        try{
           userService.changePassword(changePasswordVo,id);
            return Result.success("修改成功!");

        }catch (Exception e){
            // 捕獲異常,獲取異常信息
            String message = e.getMessage();
            // 如果修改失敗,返回失敗的結(jié)果,并附帶異常信息
            return Result.failed(message);
        }
    }

1.注解 @PutMapping("/update/pwd/{id}")

  • @PutMapping 是Spring MVC中的一個(gè)注解,用于處理HTTP PUT請(qǐng)求。
  • "/update/pwd/{id}" 是該方法的URL路徑。其中 {id} 是一個(gè)路徑變量,用于接收用戶ID。

2.方法定義 public Result update(...)

  • 這是一個(gè)公開(kāi)的方法,名為update,返回一個(gè)Result對(duì)象。
  • Result 很可能是一個(gè)自定義的響應(yīng)類,通常用于封裝API的響應(yīng)結(jié)果,包括狀態(tài)碼、消息和數(shù)據(jù)等。

3.方法參數(shù)

  • @PathVariable("id") long id:這是從URL路徑中提取的id變量。@PathVariable 注解告訴Spring MVC從URL中提取名為id的變量值,并將其轉(zhuǎn)換為long類型。
  • @RequestBody ChangePasswordVo changePasswordVo@RequestBody 注解用于將HTTP請(qǐng)求體中的JSON數(shù)據(jù)轉(zhuǎn)換為ChangePasswordVo類型的對(duì)象。ChangePasswordVo 可能是一個(gè)包含舊密碼和新密碼等信息的DTO(數(shù)據(jù)傳輸對(duì)象)。

4.方法體

  • 首先,它嘗試調(diào)用 userService.changePassword(changePasswordVo,id);。這里假設(shè)userService是一個(gè)已經(jīng)注入的服務(wù)類,用于處理與用戶相關(guān)的業(yè)務(wù)邏輯。changePassword 方法可能會(huì)根據(jù)提供的用戶ID和密碼信息來(lái)更新用戶的密碼。
  • 如果上述操作成功,方法將返回一個(gè)表示成功的Result對(duì)象,并附帶消息“修改成功!”。

如果在更新密碼的過(guò)程中發(fā)生異常(如數(shù)據(jù)庫(kù)錯(cuò)誤、密碼驗(yàn)證失敗等),catch 塊將捕獲該異常,并獲取其消息。然后,它返回一個(gè)表示失敗的Result對(duì)象,并附帶異常的消息。

entity(VO-ChangePasswordVo)

@Data
public class ChangePasswordVo implements Serializable {

    /**
     * 舊的密碼
     */
    private String oldpassword;


    /**
     * 新的密碼
     */
    private String newpassword;

}

1.注解

  • @Data: 這是一個(gè)Lombok庫(kù)提供的注解。當(dāng)你添加@Data到類上時(shí),Lombok會(huì)自動(dòng)為這個(gè)類生成getter、setter、equals、hashCode和toString方法。這可以大大減少模板代碼的數(shù)量,使代碼更加簡(jiǎn)潔。
  • implements Serializable: 這表示該類實(shí)現(xiàn)了Serializable接口。Serializable是一個(gè)標(biāo)記接口,用于指示一個(gè)類的對(duì)象可以被序列化。序列化是將對(duì)象狀態(tài)轉(zhuǎn)換為字節(jié)流,以便可以將其寫入文件或發(fā)送到網(wǎng)絡(luò)上的另一個(gè)位置。如果該類或其成員類(如果它們不是基本類型或String、數(shù)組等)需要被序列化,則必須實(shí)現(xiàn)這個(gè)接口。

2.成員變量

  • private String oldpassword;: 這是一個(gè)私有字符串類型的成員變量,用于存儲(chǔ)舊的密碼。但是,從Java的命名約定來(lái)看,變量名應(yīng)該使用駝峰命名法(camelCase),并且首字母小寫。因此,更合適的命名可能是oldPassword
  • private String newpassword;: 同樣,這是一個(gè)私有字符串類型的成員變量,用于存儲(chǔ)新的密碼。按照J(rèn)ava的命名約定,它應(yīng)該被命名為newPassword。

3.注釋

  • 每個(gè)成員變量上方都有注釋,描述了該變量的用途。
  • 這是一個(gè)很好的做法,因?yàn)樗黾恿舜a的可讀性。
  • 但是,請(qǐng)注意,這些注釋是用中文寫的,而在國(guó)際項(xiàng)目中,通常建議使用英文注釋。

Service

UserService

void changePassword(ChangePasswordVo changePasswordVo, Long id);

1.返回類型 (void): 方法前面有一個(gè)void關(guān)鍵字,表示這個(gè)方法沒(méi)有返回值。也就是說(shuō),當(dāng)你調(diào)用這個(gè)方法時(shí),它不會(huì)返回任何值或?qū)ο蟆?/p>

2.方法名 (changePassword): 這是方法的名稱,即changePassword。當(dāng)你想在代碼的其他部分調(diào)用這個(gè)方法時(shí),你會(huì)使用這個(gè)名字。

參數(shù)

ChangePasswordVo changePasswordVo: 這是方法的第一個(gè)參數(shù)。

  • ChangePasswordVo: 這是參數(shù)的類型。它可能是一個(gè)數(shù)據(jù)傳輸對(duì)象(DTO),用于封裝與更改密碼相關(guān)的數(shù)據(jù),如舊密碼、新密碼等。
  • changePasswordVo: 這是參數(shù)的名稱。在方法內(nèi)部,你可以使用這個(gè)名稱來(lái)引用傳入的ChangePasswordVo對(duì)象。

Long id: 這是方法的第二個(gè)參數(shù)。

  • Long: 這是參數(shù)的類型,表示這是一個(gè)長(zhǎng)整型(64位整數(shù))數(shù)據(jù)。
  • id: 這是參數(shù)的名稱。在方法內(nèi)部,你可以使用這個(gè)名稱來(lái)引用傳入的id值。從參數(shù)名可以推測(cè),這個(gè)id可能表示用戶的唯一標(biāo)識(shí)符(如用戶ID)。

UserServiceImpl

 @Override
   public void changePassword(ChangePasswordVo changePasswordVo, Long id){
       // 根據(jù)id查詢用戶信息
       User user = userMapper.selectById(id);
       // 判斷原密碼是否正確
       if(!BCrypt.checkpw(changePasswordVo.getOldpassword(),user.getPassword())){
           throw new RuntimeException("原密碼不正確");
       }
       // 設(shè)置新密碼
       user.setPassword(BCrypt.hashpw(changePasswordVo.getNewpassword(), BCrypt.gensalt()));
       // 調(diào)用Mapper的updateById方法更新用戶信息
       userMapper.updateById(user);
   }

1.@Override

  • 這是一個(gè)Java注解,它告訴編譯器這個(gè)方法是從超類或接口中繼承或?qū)崿F(xiàn)的。
  • 使用@Override注解可以確保你正確地重寫了父類或接口中的方法,如果沒(méi)有正確重寫(例如方法簽名不匹配),編譯器會(huì)報(bào)錯(cuò)。

2.public void changePassword(ChangePasswordVo changePasswordVo, Long id): 這是方法的聲明部分。

  • public:表示這是一個(gè)公共方法,可以從任何其他類中被訪問(wèn)。
  • void:表示該方法沒(méi)有返回值。
  • changePassword:是方法的名稱。
  • ChangePasswordVo changePasswordVoLong id:是方法的參數(shù)。ChangePasswordVo可能是一個(gè)數(shù)據(jù)傳輸對(duì)象(DTO),用于封裝密碼更改請(qǐng)求所需的信息(如舊密碼和新密碼)。id則是用戶的唯一標(biāo)識(shí)符。

3.User user = userMapper.selectById(id);

  • 使用userMapper(可能是MyBatis的Mapper或類似的ORM工具)的selectById方法根據(jù)提供的id從數(shù)據(jù)庫(kù)中查詢用戶信息,并將查詢到的用戶信息存儲(chǔ)在user變量中。

4.if(!BCrypt.checkpw(changePasswordVo.getOldpassword(),user.getPassword())){

  • 使用BCrypt庫(kù)(一個(gè)流行的密碼哈希庫(kù))的checkpw方法檢查用戶提供的舊密碼(從changePasswordVo中獲取)是否與數(shù)據(jù)庫(kù)中存儲(chǔ)的哈希密碼(從查詢到的user對(duì)象中獲?。┢ヅ洹?/li>
  • 如果不匹配(!BCrypt.checkpw(...)返回true),則執(zhí)行下面的throw語(yǔ)句。

5.throw new RuntimeException("原密碼不正確");

  • 如果舊密碼不正確,則拋出一個(gè)RuntimeException,并帶有消息“原密碼不正確”。調(diào)用此方法的代碼應(yīng)該捕獲此異常并適當(dāng)?shù)靥幚硭ɡ?,向用戶顯示錯(cuò)誤消息)。

6.user.setPassword(BCrypt.hashpw(changePasswordVo.getNewpassword(), BCrypt.gensalt()));

  • 如果舊密碼正確,則使用BCrypt庫(kù)的gensalt方法生成一個(gè)新的隨機(jī)鹽值。
  • 使用這個(gè)新鹽值和用戶提供的新密碼(從changePasswordVo中獲取)作為參數(shù),調(diào)用BCrypthashpw方法生成新的哈希密碼。
  • 將這個(gè)新的哈希密碼設(shè)置到user對(duì)象的password字段中。

7.userMapper.updateById(user);

  • 使用userMapperupdateById方法更新數(shù)據(jù)庫(kù)中對(duì)應(yīng)id的用戶的密碼信息。
  • 這里假設(shè)userMapperupdateById方法會(huì)處理將user對(duì)象中的更改保存到數(shù)據(jù)庫(kù)中的邏輯。

測(cè)試

先新增一條數(shù)據(jù)

密碼:111

進(jìn)行修改密碼;

id為你新增后的id號(hào)

輸入字段為我之前定義的字段oldpassword與newpassword

可以看到密碼已經(jīng)被修改

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論