一、核心功能实现
1. 用户注册功能
前端实现
-
用户名实时校验:通过AJAX异步请求检查用户名是否已存在。
function checkName() { $.ajax({ url: '/users/checkUserName?uname=' + uname, success: function(resp) { if (resp.code == 200) alert("用户名可用"); else $("#info").html("<font color='red'>用户名已被注册</font>"); } }); }
-
密码一致性校验:提交前验证两次输入的密码是否一致
if (ps != rps) { alert("两次密码输入不一致"); return; }
-
表单提交:使用
serialize()
方法序列化表单数据并发送POST请求。$.ajax({ url: '/users/register', data: $("#form-reg").serialize(), success: function(resp) { if (resp.code == 200) window.location.href = "/login.html"; } });
后端实现
-
控制器层:处理注册请求,返回JSON结果。
@RestController @RequestMapping("/users") public class UserController { @PostMapping("/register") public JsonResult register(User user) { boolean flag = userService.register(user); return flag ? new JsonResult(OK) : new JsonResult(FALL); } }
-
服务层:密码加密(MD5加盐)及用户数据持久化。
public boolean register(User user) { String md5Password = getMd5Password(user.getPassword(), user.getUsername()); user.setPassword(md5Password); return userMapper.insert(user) > 0; }
-
数据层:通过MyBatis操作数据库。
<insert id="register"> INSERT INTO t_user (username, password, salt) VALUES (#{username}, #{password}, #{salt}); </insert>
2. 用户登录功能
前端实现
-
回车键触发登录:监听键盘事件,回车键提交表单。
$(window).keydown(function(e) { if (e.keyCode == 13) $("#btn-login").click(); });
-
登录请求:提交用户名和密码至后端验证。
$.ajax({ url: '/users/login', data: $("#form-login").serialize(), success: function(resp) { if (resp.code == 200) window.location.href = "/index.html"; } });
后端实现
-
控制器层:验证用户信息并存储会话。
@PostMapping("/login") public JsonResult login(User user, HttpSession session) { User dbUser = userService.login(user); session.setAttribute("uid", dbUser.getUid()); return new JsonResult(OK); }
-
服务层:校验用户状态与密码。
public User login(User user) { User dbUser = userMapper.getUserByUsername(user.getUsername()); if (dbUser == null) throw new UserNotFoundException("用户不存在"); if (!validatePassword(user.getPassword(), dbUser.getSalt(), dbUser.getPassword())) { throw new PasswordNotMatchException("密码错误"); } return dbUser; }
二、安全与优化策略
1. 密码安全
-
加密方式:使用MD5加盐(盐值为用户名)加密密码。
private String getMd5Password(String password, String salt) { for (int i = 0; i < 3; i++) { password = DigestUtils.md5DigestAsHex((salt + password + salt).getBytes()); } return password; }
-
改进建议:推荐使用BCrypt等更安全的哈希算法,并生成随机盐值。
2. 防御措施
-
SQL注入防护:通过MyBatis参数绑定(
#{param}
)避免注入。 -
会话管理:用户登录后通过Session存储UID,敏感操作需校验Session有效性。
-
输入校验:后端需重复验证用户名和密码格式(如长度、特殊字符)。
三、页面状态管理
1. 动态菜单显示
-
未登录状态:显示“登录”和“注册”链接。
if (id == 0) { $("#mymenu").append("<li><a href='/login'>登录</a></li>"); }
-
已登录状态:显示用户ID和“退出”按钮。
if (id != 0) { $("#mymenu").append("<li>用户ID:" + id + "</li>"); $("#mymenu").append("<li><a href='javascript:logout()'>退出</a></li>"); }
四、商品检索功能
1. 前端实现
-
搜索表单提交:跳转至搜索页并携带参数。
<form action="/search.html" onsubmit="return validateSearch()"> <input type="text" id="search" name="keyword"> <button type="submit">搜索</button> </form>
-
解析URL参数:获取关键字并发送请求。
const keyword = new URLSearchParams(window.location.search).get("keyword"); $.ajax({ url: '/product/search?keyword=' + keyword, success: function(resp) { /* 渲染结果 */ } });
2. 后端实现
-
模糊查询:通过SQL的
LIKE
实现。<select id="searchProducts"> SELECT * FROM t_product WHERE title LIKE CONCAT('%', #{keyword}, '%'); </select>