Maison > Article > interface Web > Spring shiro bootstrap jquery.validate méthode d'implémentation des fonctions de connexion et d'enregistrement
Cet article présente principalement Spring shiro + bootstrap + jquery.validate pour implémenter les fonctions de connexion et d'enregistrement. J'espère que cela pourra aider tout le monde.
Dans l'article précédent, nous avons déjà construit le framework et conçu la base de données.
Nous commençons maintenant à implémenter la fonction de connexion, qui peut être considérée comme la fonction la plus courante des applications Web.
Parlons d'abord de notre logique de connexion :
Entrez le nom d'utilisateur et le mot de passe (validez pour la vérification frontale) - ajax appelle la méthode d'action en arrière-plan - appelle la couche métier à la couche de données en fonction sur le nom d'utilisateur Interroger les informations de la base de données - comparer le mot de passe demandé avec le mot de passe saisi par l'utilisateur - authentification de connexion shiro - stocker les informations de l'utilisateur en session - répondre au front-end - sauter au front-end
C'est ce que je veux pour vous dire des poses, et il y en a beaucoup, beaucoup d'autres. Regardons le code spécifique ci-dessous.
Tout d'abord, la vérification frontale, jquery.validate est utilisé ici pour la vérification. L'utilisation de jquery.validate est très simple. Nous parlons ici de la façon de sauvegarder js :
.
$().ready(function() { /**登录验证**/ $("#login_form").validate({ rules: { loginAccount: "required", loginPass: { required: true, minlength: 5 }, }, messages: { loginAccount: "请输入姓名", loginPass: { required: "请输入密码", minlength: jQuery.format("密码不能小于{0}个字 符") }, }, submitHandler:function(form){ $.ajax({ dataType : "json", url : "sysuser/login.action", type : "post", data : $("#login_form").serialize(), success : function(data) { $.alert(data.message); if(data.success){ window.location.href = 'page/main.action'; } }, error : function (e){ var d = e.responseJSON; if(d){ $.alert(d.message); } } }); return false; //阻止form提交 } }); /**注册验证**/ $("#register_form").validate({ rules: { loginAccount:{ required:true, remote: { url: "sysuser/getUserNameCount.action", type: "post", dataType: "json", data: { loginAccount: function () { return $("#register_account").val(); } }, dataFilter: function (data) { //判断控制器返回的内容 data = jQuery.parseJSON(data); return data.success; } } }, loginPass: { required: true, minlength: 5, maxlength:20 }, rloginPass: { equalTo: "#register_password" }, userEmail: { required: true, email: true, remote: { url: "sysuser/getEMailCount.action", type: "post", dataType: "json", data: { email: function () { return $("#register_email").val(); } }, dataFilter: function (data) { //判断控制器返回的内容 data = jQuery.parseJSON(data); return data.success; } } } }, messages: { loginAccount:{ required: "请输入姓名", remote: "用户名已存在" }, loginPass: { required: "请输入密码", minlength: jQuery.format("密码不能小于{0}个字 符"), maxlength: jQuery.format("密码不能大于{0}个字 符"), }, rloginPass: { required: "请输入确认密码", equalTo: "两次密码不一样" }, userEmail: { required: "请输入邮箱", email: "请输入有效邮箱", remote: "邮箱已存在" } }, submitHandler:function(form){ $.ajax({ dataType : "json", url : "sysuser/register.action", type : "post", data : $("#register_form").serialize(), success : function(data) { $.alert(data.message); if(data.success){ window.location.href = 'page/main.action'; } }, error : function (e){ var d = e.responseJSON; if(d){ $.alert(d.message); } } }); return false; //阻止form提交 } }); /**隐藏显示登录注册**/ $("#register_btn").click(function() { $("#register_form").css("display", "block"); $("#login_form").css("display", "none"); }); $("#back_btn").click(function() { $("#register_form").css("display", "none"); $("#login_form").css("display", "block"); }); });
page html :
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <c:set var="contextPath" value="${pageContext.request.contextPath}"></c:set> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content=""> <meta name="author" content=""> <title>主页</title> <!-- Bootstrap core CSS --> <link href="${contextPath }/static/bootstrap/css/bootstrap.min.css" rel="external nofollow" rel="stylesheet"> <link href="${contextPath }/static/bootstrap/css/font-awesome.min.css" rel="external nofollow" rel="stylesheet"> <link href="${contextPath }/static/alert/jquery-confirm.min.css" rel="external nofollow" rel="stylesheet"> <style type="text/css"> body { background: url(${contextPath }/static/img/login/bg.jpg) no-repeat; background-size: cover; font-size: 16px; } .form { background: rgba(255, 255, 255, 0.2); width: 400px; margin: 100px auto; } #login_form { display: block; } #register_form { display: none; } .fa { display: inline-block; top: 27px; left: 6px; position: relative; color: #ccc; } input[type="text"], input[type="password"] { padding-left: 26px; } .checkbox { padding-left: 21px; } </style> <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> <!--[if lt IE 9]> <script src="${contextPath }/static/bootstrap/html5shiv/html5shiv.js"></script> <script src="${contextPath }/static/bootstrap/respond/respond.min.js"></script> <![endif]--> </head> <body> <p class="container"> <p class="form row"> <form class="form-horizontal col-sm-offset-3 col-md-offset-3" id="login_form"> <h3 class="form-title">登录</h3> <p class="col-sm-9 col-md-9"> <p class="form-group"> <i class="fa fa-user fa-lg"></i> <input class="form-control required" type="text" placeholder="请输入账号" name="loginAccount" autofocus="autofocus" maxlength="20" /> </p> <p class="form-group"> <i class="fa fa-lock fa-lg"></i> <input class="form-control required" type="password" placeholder="请输入密码" name="loginPass" maxlength="8" /> </p> <p class="form-group"> <label class="checkbox"> <input type="checkbox" name="rememberMe" value="1" /> 记住我 </label> <hr /> <a href="javascript:;" rel="external nofollow" id="register_btn" class="">注册?</a> </p> <p class="form-group"> <input type="submit" class="btn btn-success pull-right" value="登录 " /> </p> </p> </form> </p> <p class="form row"> <form class="form-horizontal col-sm-offset-3 col-md-offset-3" id="register_form"> <h3 class="form-title">注册</h3> <p class="col-sm-9 col-md-9"> <p class="form-group"> <i class="fa fa-user fa-lg"></i> <input class="form-control required" type="text" placeholder="请输入账号" name="loginAccount" autofocus="autofocus" id="register_account" /> </p> <p class="form-group"> <i class="fa fa-lock fa-lg"></i> <input class="form-control required" type="password" placeholder="请输入密码" id="register_password" name="loginPass" /> </p> <p class="form-group"> <i class="fa fa-check fa-lg"></i> <input class="form-control required" type="password" placeholder="请输入确认密码" name="rloginPass" /> </p> <p class="form-group"> <i class="fa fa-envelope fa-lg"></i> <input class="form-control eamil" type="text" placeholder="Email" name="userEmail" id="register_email"/> </p> <p class="form-group"> <input type="submit" class="btn btn-success pull-right" value="注册" /> <input type="submit" class="btn btn-info pull-left" id="back_btn" value="返回" /> </p> </p> </form> </p> </p> <script type="text/javascript" src="${contextPath }/static/jquery/jquery.min.js"></script> <script type="text/javascript" src="${contextPath }/static/bootstrap/js/bootstrap.min.js"></script> <script type="text/javascript" src="${contextPath }/static/alert/jquery-confirm.min.js" ></script> <script type="text/javascript" src="${contextPath }/static/jquery/jquery.validate.min.js" ></script> <script type="text/javascript" src="${contextPath }/static/login/login.js" ></script> </body> </html>
dans le $("#login_form").validate ({...}) méthode Dans, login_form est l'identifiant du formulaire que vous souhaitez vérifier ; les règles sont les champs à vérifier ; les messages sont le contenu à demander. S'il n'est pas renseigné, le message par défaut sera demandé ; submitHandler est la méthode de rappel après avoir cliqué sur le bouton Soumettre. Ceci Le dernier retour false à l'intérieur est d'empêcher la soumission du formulaire, car je veux le soumettre ici en utilisant ajax, il y a un attribut distant dans le champ loginAccount dans l'enregistrement. est pour la vérification ajax. Avant que le formulaire ne soit soumis, nous le vérifions si le nom d'utilisateur saisi par l'utilisateur existe déjà dans le système.
Lorsque nous programmons, nous constatons qu'il existe toujours plusieurs méthodes utilisées dans la même couche de code, comme l'obtention d'une session utilisateur dans la couche de contrôle, ou la sortie d'informations de réponse, etc. layer Appelez la méthode de sauvegarde, la méthode de mise à jour, la méthode de suppression d'Hibernate, etc. Par conséquent, nous devrions établir des classes d'outils ou des méthodes de base communes dès les premières étapes de la construction du framework. Ensuite, nous créerons une nouvelle méthode BaseController et laisserons les contrôleurs suivants en hériter.
import java.io.IOException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.web.bind.annotation.ModelAttribute; import com.fasterxml.jackson.core.JsonEncoding; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.ObjectMapper; import yfkj.gz.task.entity.SysUser; import yfkj.gz.task.util.Result; /** * 父类控制器 * @author 胡汉三 * @date 2017年1月9日 下午5:23:52 */ @SuppressWarnings("deprecation") public class BaseController{ public static final String USER_SESSION = "USER_SESSION"; protected static ObjectMapper mapper = new ObjectMapper(); protected static JsonFactory factory = mapper.getJsonFactory(); protected static Result result = new Result(); protected HttpServletRequest request; protected HttpServletResponse response; protected HttpSession session; @ModelAttribute public void setReqAndRes(HttpServletRequest request, HttpServletResponse response){ this.request = request; this.response = response; this.session = request.getSession(); } /**将json字符串输出**/ protected void writeJSON(String json) throws IOException { response.setContentType("text/html;charset=utf-8"); response.getWriter().write(json); } /**将对象转成json输出**/ protected void writeJSON(Object obj) throws IOException { response.setContentType("text/html;charset=utf-8"); JsonGenerator responseJsonGenerator = factory.createJsonGenerator(response.getOutputStream(), JsonEncoding.UTF8); responseJsonGenerator.writeObject(obj); } /** * 获得session用户对象 * @return */ protected SysUser getUser(){ Object userObj = session.getAttribute(USER_SESSION); if(userObj == null){ return null; } return (SysUser)userObj; } }
Contrôleur de l'utilisateur SysUserController :
package yfkj.gz.task.controller; import java.io.IOException; import java.util.Date; import java.util.List; import javax.annotation.Resource; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.crypto.hash.Sha256Hash; import org.apache.shiro.subject.Subject; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import yfkj.gz.task.entity.SysRole; import yfkj.gz.task.entity.SysUser; import yfkj.gz.task.service.ISysRoleService; import yfkj.gz.task.service.ISysUserService; import yfkj.gz.task.util.DateUtil; import yfkj.gz.task.util.StringUtils; import yfkj.gz.support.BTView; import yfkj.gz.support.controller.BaseController; /** * 用户控制器 * @author 胡汉三 * @date 2017年1月16日 下午2:31:39 */ @Controller @RequestMapping("/sysuser") public class SysUserController extends BaseController{ @Resource private ISysUserService userService; @Resource private ISysRoleService roleService; /** * 分页查询用户 * @param response * @param user * @param btView * @throws IOException */ @RequestMapping(value = "/findUser", method = { RequestMethod.POST, RequestMethod.GET }) public void findUser(SysUser user,BTView<SysUser> btView) throws IOException{ List<SysUser> list = userService.findSysUserPage(btView, null); btView.setRows(list); super.writeJSON(btView); } /** * 用户登录 * @param response * @param user * @throws IOException */ @RequestMapping(value = "/login", method = { RequestMethod.POST, RequestMethod.GET }) public void login(SysUser user,boolean rememberMe) throws IOException{ //用户登录 SysUser userInfo = userService.getByProerties(new String[]{"loginAccount"}, new String[]{user.getLoginAccount()},null); if(userInfo==null){ result.setMessage("用户名错误"); super.writeJSON(result); return; } if(!userInfo.getLoginPass().equals(new Sha256Hash(user.getLoginPass()).toHex())){ result.setMessage("密码错误"); super.writeJSON(result); return; } //存入session Subject subject = SecurityUtils.getSubject(); //记得传入明文密码 subject.login(new UsernamePasswordToken(userInfo.getLoginAccount(), user.getLoginPass(), rememberMe)); session.setAttribute(USER_SESSION, userInfo); result.setMessage("登录成功"); result.setSuccess(true); super.writeJSON(result); } /** * 用户注册 * @param response * @param user * @throws IOException */ @RequestMapping(value = "/register", method = { RequestMethod.POST, RequestMethod.GET }) public void register(SysUser user) throws IOException{ Long count = userService.getCountByProerties(new String[]{"loginAccount"}, new String[]{user.getLoginAccount()}); if(count>0){ result.setMessage("账号已存在"); super.writeJSON(result); return; } Long countEmail = userService.getCountByProerties(new String[]{"userEmail"}, new String[]{user.getUserEmail()}); if(countEmail>0){ result.setMessage("邮箱已存在"); super.writeJSON(result); return; } try{ //注册时间 user.setRegisterTime(DateUtil.getDateTime(new Date())); //Sha256Hash加密 user.setLoginPass(new Sha256Hash(user.getLoginPass()).toHex()); //默认为注册用户 SysRole role = roleService.getByProerties(new String[]{"roleKey"},new String[]{"ROLE_USER"},null); user.getRoles().add(role); userService.save(user); //存入session Subject subject = SecurityUtils.getSubject(); subject.login(new UsernamePasswordToken(user.getLoginAccount(), user.getLoginPass())); session.setAttribute(USER_SESSION, user); result.setMessage("注册成功"); result.setSuccess(true); }catch(Exception e){ result.setMessage("注册失败"); } super.writeJSON(result); } /** * 判断用户账号是否已存在 * @param response * @param user * @throws IOException */ @RequestMapping(value = "/getUserNameCount", method = { RequestMethod.POST, RequestMethod.GET }) public void getUserNameCount(String loginAccount) throws IOException{ result.setSuccess(false); if(StringUtils.isBlank(loginAccount)){ result.setMessage("账号不能为空"); super.writeJSON(result); return; } Long count = userService.getCountByProerties(new String[]{"loginAccount"}, new String[]{loginAccount}); if(count>0){ result.setMessage("账号已存在"); }else{ result.setSuccess(true); result.setMessage("该账号可用"); } super.writeJSON(result); } /** * 判断用户邮箱是否已存在 * @param response * @param email * @throws IOException */ @RequestMapping(value = "/getEMailCount", method = { RequestMethod.POST, RequestMethod.GET }) public void getEMailCount(String email) throws IOException{ result.setSuccess(false); if(StringUtils.isBlank(email)){ result.setMessage("邮箱不能为空"); super.writeJSON(result); return; } Long count = userService.getCountByProerties(new String[]{"userEmail"}, new String[]{email}); if(count>0){ result.setMessage("邮箱已存在"); }else{ result.setSuccess(true); result.setMessage("该邮箱可用"); } super.writeJSON(result); } // 登出 @RequestMapping("/logout") public void logout() throws IOException { //退出权限验证 SecurityUtils.getSubject().logout(); //销毁session session.invalidate(); response.sendRedirect(request.getContextPath()+"/login.jsp"); } }
À ce stade, Connectez-vous et inscrivez-vous !
jquery-confirm.js est également utilisé, qui est un plug-in de boîte pop-up : cliquez pour voir
recommandations associées :
Vue se rend compte que la page passe à la page précédente après la connexion
Méthode AJAX pour réaliser le non-rafraîchissement. fonction de connexion
La fonction permettant de déterminer si l'utilisateur est connecté lorsque l'itinéraire Vue saute
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!