利用 passay 來作密碼規則驗證與自動產生密碼
密碼原則是常來驗證使用者輸入是否過於簡單,要自已寫一套當然可以,但若有已經寫好的,那麼直接拿來使用,這樣可以加速應用程式的開發,這是不是更好呢? passay 就是一套可以用來作密碼規則驗證與自動產生密碼的套件,建議您不妨可以直接拿來使用。
首先,先加入對 passay 的相依套件。
dependencies { compile("org.passay:passay:1.4.0") // 密碼規則驗證與產生 }
再來建立你想要的規則
/** * 密碼規則 * 1.8-6 個字元 * 2. 至少一個英文大寫 * 3. 至少一個英文小寫 * 4. 至少一個數字 * 5. 不可以與 username 相同 * 6. 不可以有空白字元 * @return */ public List<Rule> passwordRules() { List<Rule> pr = new ArrayList<Rule>(); // length between 8 and 16 characters pr.add(new LengthRule(8, 16)); // at least one upper-case character pr.add(new CharacterRule(EnglishCharacterData.UpperCase, 1)); // at least one lower-case character pr.add(new CharacterRule(EnglishCharacterData.LowerCase, 1)); // at least one digit character pr.add(new CharacterRule(EnglishCharacterData.Digit, 1)); // password can not same as username pr.add(new UsernameRule()); // no whitespace pr.add(new WhitespaceRule()); return pr; }
用於自動產生密碼時,使用 instanceof
來取得符合 CharacterRule
的規則。
/** * 依 passwordRules() 來產生8個字元的密碼 * @return */ public String generatePassword() { PasswordGenerator passwordGenerator = new PasswordGenerator(); List<CharacterRule> rs = new ArrayList<CharacterRule>(); List<Rule> rules = this.passwordRules(); for (Rule rule : rules) { if (rule instanceof CharacterRule) { CharacterRule cr = (CharacterRule) rule; rs.add(cr); } } return passwordGenerator.generatePassword(8,rs); }
驗證密碼時,若想要產生多語系的訊息時,可以參考 Spring Boot 讀取自定多語系 properties 檔 來自定義錯誤訊息。
/** * 依 passwordRules() 的密碼規則來驗證 * @param username * @param password * @param locale * @return * @throws FileNotFoundException * @throws IOException */ public Map passwordIsValid(String username, String password, Locale locale) throws FileNotFoundException, IOException { ReloadableResourceBundleMessageSource ms = new ReloadableResourceBundleMessageSource(); ms.setBasename("classpath:PasswordMessages"); ms.setDefaultEncoding("UTF-8"); SpringMessageResolver smr = new SpringMessageResolver(ms, locale); PasswordValidator validator = new PasswordValidator(smr,this.passwordRules()); PasswordData pd = new PasswordData(username, password); RuleResult result = validator.validate( pd ); Map validResult = new LinkedHashMap<>(); if(result.isValid()){ validResult.put("isValid", true); validResult.put("message", validator.getMessages(result)); } else { validResult.put("isValid", false); validResult.put("message", validator.getMessages(result)); } return validResult; }
最後,建立測試程式來試試看,這樣很快速吧。
@SpringBootTest class AppsApplicationTests { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired SystemService sysService; @Test void testPasswordRules() throws FileNotFoundException, IOException { Locale locale = Locale.TRADITIONAL_CHINESE; Map result = sysService.passwordIsValid("user","userpwd123" , locale); System.out.println(result.get("isValid")); System.out.println(result.get("message")); } @Test void testPasswordGenerate() { System.out.println(sysService.generatePassword()); } }
密碼驗證的輸出結果
false [密碼必須包含 1 個或多個大寫字符。, 密碼包含為用戶 ID: user 。]
你必須 登入 才能發表評論。