Spring Boot登录功能开发问题:如何从Repository提取数据并实现登录验证逻辑
解决登录校验的两个问题 + 修复Repo查询逻辑
嘿,我来帮你一步步搞定这两个问题,顺便提个你的Repo里的关键问题——现在的查询逻辑其实不符合登录校验的需求,先给你指出来,不然即使Controller逻辑对了,也可能出现错误的匹配~
问题1:如何将user.getUsername()和user.getPassword()存入列表?
你代码里已经定义了List<String> dati,只要在确认utenti不为空后,直接把两个值添加进去就行,记得先判空避免空指针:
if(utenti!=null && utenti.getUsername() != null && utenti.getPassword() != null) { String username = utenti.getUsername().trim(); String password = utenti.getPassword().trim(); // 存入列表 dati.add(username); dati.add(password); log.info(password + " " + username ); // 后续调用Repo的逻辑... }
这里加了trim()是为了去除前后空格,避免用户输入空格导致的匹配失败,算是小细节优化。
问题2:处理Repo返回结果,实现登录校验跳转
首先你需要接收Repo方法的返回值,然后根据返回的列表是否为空来判断凭证是否有效,同时还要先校验用户输入的用户名/密码是不是空字符串,步骤如下:
第一步:修改Controller代码,添加校验逻辑
@PostMapping("/controllo") public String logOk(@ModelAttribute("utenteForm") UtentiModel utenti, Model model) { log.info("Controllo i dati che mi stanno arrivando dall'utente: "); List<String> dati= new ArrayList<String>(); // 1. 先校验用户输入是否为空 if(utenti == null || utenti.getUsername() == null || utenti.getPassword() == null || utenti.getUsername().trim().isEmpty() || utenti.getPassword().trim().isEmpty()) { return "errorPage"; } String username = utenti.getUsername().trim(); String password = utenti.getPassword().trim(); dati.add(username); dati.add(password); log.info(password + " " + username ); // 2. 调用Repo方法并接收返回结果 List<UtentiModel> matchedUsers = utentiRepo.ByPassAndUsername(password, username); // 3. 判断是否匹配:列表非空且有数据则跳转欢迎页,否则错误页 if(matchedUsers != null && !matchedUsers.isEmpty()) { // 可以把用户信息存入Model,方便欢迎页展示 model.addAttribute("currentUser", matchedUsers.get(0)); return "welcome"; } else { return "errorPage"; } }
第二步:修复Repo的查询逻辑(关键!)
你现在的ByPassAndUsername方法用了拼接用户名+密码、密码+用户名然后模糊匹配的逻辑,这完全不符合登录校验的需求——登录应该是精确匹配用户名和密码,不然会出现很多错误匹配的情况(比如输入"a"和"b",数据库里有"ab"和""的用户也会被匹配到)。修改后的Repo方法如下:
@Override public List<UtentiModel> ByPassAndUsername(String password, String username) { CriteriaBuilder queryBuilder= em.getCriteriaBuilder(); CriteriaQuery<UtentiModel> query= queryBuilder.createQuery(UtentiModel.class); Root<UtentiModel> rec= query.from(UtentiModel.class); // 精确匹配用户名和密码,用and连接两个条件 Predicate p = queryBuilder.and( queryBuilder.equal(rec.get("username"), username), queryBuilder.equal(rec.get("password"), password) ); query.select(rec).where(p); List<UtentiModel> ut= em.createQuery(query).getResultList(); em.clear(); return ut; }
这样修改后,只有当数据库中存在完全匹配用户名和密码的用户时,才会返回非空列表。
额外的最佳实践建议
现在你的密码是明文存储的,这非常不安全,建议使用加密算法(比如BCrypt)存储密码。存储时对密码进行加密,登录时对用户输入的密码进行同样的加密后再和数据库中的密文对比,这样能大大提升安全性。
内容的提问来源于stack exchange,提问作者helloJava




