登陆的逻辑是:(校验用户手机号和验证码是否匹配)
用户需要先注册才能登陆,所以登陆时数据中其实已经存在用户的信息,所以登陆时只需获取用户的手机号和密码,再去查询数据中该用户的手机号和密码与其输入的是否匹配,若是匹配则表示是同一个用户,显示登陆成功,跳转到详情页,否则提示登录失败。
下面,结合代码整理下流程:
(1)前端显示登陆页面用于用户填写用户信息:
<body class="login">
<div class="content">
<h3 class="form-title">用户登陆</h3>
<div class="form-group">
<label class="control-label">手机号</label>
<div>
<input class="form-control" type="text" placeholder="手机号" name="telephone" id="telephone">
</div>
</div>
<div class="form-group">
<label class="control-label">密码</label>
<div>
<input class="form-control" type="text" placeholder="密码" name="password" id="password">
</div>
</div>
<div class="form-actions">
<button class="btn blue" id="login" type="submit">
登陆
</button>
<button class="btn green" id="register" type="submit">
注册
</button>
</div>
</div>
</body>
通过jquery在用户点击提交注册按钮时发送ajax请求:
在这个请求中,设置请求类型为post,请求的内容类型为:application/x-www-form-urlencoded,请求的url(对应后台的处理函数):/user/login,要发送到服务器的数据放在data中,最后用函数success:function()接收后台传递的结果,根据结果确定是跳转到详情页h还是告诉用户登陆失败:
$.ajax({
type:"POST",
contentType:"application/x-www-form-urlencoded",
url:"http://localhost:8090/user/login",
data:{
"telephone":$("#telephone").val(),//传递的参数
"password":password
},
xhrFields:{withCredentials:true},
success:function (data) {
if(data.status=="success"){
alert("登陆成功");
window.location.href="http://localhost:63342/mymiaoshaproject/listitem.html?_ijt=kagfuh9opg59v86iops2usnam2";
// window.location.href="listitem.html";
}else {
alert("登陆失败,原因为:"+data.data.errMsg);
}
},
error:function (data) {
alert("登陆失败,原因为:"+data.responseText);
}
});
登陆的前端页面:
(2)controller层处理:
在UserController类中编写一个方法login,添加 @RequestMapping注解,映射前端设置的url路径/user/login;添加 @ResponseBody,将后台处理后的结果(数据)返回给前端。
在login()方法中添加注解@RequestParam指定获取前端的数据,然后进行入参判空校验,然后调用service层的方法validateLogin(telephone,this.EncodeByMd5(password));返回的数据放在user model中。校验用户是否合法,该方法包含两个参数,一个前端传递来的电话号码,一个是密码,这个密码在进行传输时需要加密,于是编写了一个加密方法: EncodeByMd5():
加密方法的代码:
public String EncodeByMd5(String str) throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest md5=MessageDigest.getInstance("MD5");
BASE64Encoder base64en=new BASE64Encoder();
//加密字符串
String newstr=base64en.encode(md5.digest(str.getBytes("utf-8")));
return newstr;
}
接着,在这个请求中,将用户的登陆凭证存入session中
再调用通用的返回类创建返回的方法,注册时只需将用户手机号和密码插入到数据库中,没有需要返回给前端的数据,因此该方法的参数为null.
用户登陆方法(controller)
@RequestMapping(value = "/login",method = {RequestMethod.POST},consumes = {CONTENT_TYPE_FORMED})
@ResponseBody
public CommonReturnType login(@RequestParam(name = "telephone")String telephone,
@RequestParam(name="password")String password) throws BusinessException, UnsupportedEncodingException, NoSuchAlgorithmException {
//入参校验
if(StringUtils.isEmpty(telephone)||StringUtils.isEmpty(password)){
throw new BusinessException(EnumBusinessError.PARAMETER_VALIDATION_ERROR);
}
//用户登陆,用来校验用户登陆是否合法
UserModel userModel=userService.validateLogin(telephone,this.EncodeByMd5(password));
//将登陆凭证加入到用户登陆成功的session内
this.httpServletRequest.getSession().setAttribute("IS_LOGIN",true);
this.httpServletRequest.getSession().setAttribute("LOGIN_USER",userModel);
return CommonReturnType.create(null);
}
(3)service层的实现
在service包下,编写一个userservice接口,在其中添加一个校验用户登陆方法,再写一个userserviceimpl方法实现接口,并实现其中的方法:
在该方法中,首先通过用户的手机号获取用户信息,然后通过用户id获取用户密码,然后再比对用户输入的密码和数据库中的该手机号的密码是否匹配,若匹配则返回用户信息,若不匹配则报错。@Override
public UserModel validateLogin(String telephone, String encrptPassword) throws BusinessException {
//通过用户的手机号获取用户的信息
UserDO userDO=userDOMapper.selectByTelephone(telephone);
if(userDO==null) {
throw new BusinessException(EnumBusinessError.USER_LOGIN_FAIL);
}
UserPasswordDO userPasswordDO=userPasswordDOMapper.selectByUserId(userDO.getId());
UserModel userModel=convertFromDataObject(userDO,userPasswordDO);
//比对用户信息内加密的密码是否和传输进来的密码相匹配
if (!StringUtils.equals(encrptPassword,userModel.getEncryptPassword())){
throw new BusinessException(EnumBusinessError.USER_LOGIN_FAIL);
}
return userModel;
}
(4)dao层
用户登陆功能的实现在dao中主要是根据用户的手机号获取到用户的信息,再根据用户的id获取到用户的密码,返回给service层即可,在service层中判断用户输入的信息,与数据库查找到的信息是否匹配。
也就是两个查询sql,
userDOMapper.selectByTelephone(telephone);
userPasswordDOMapper.selectByUserId(userDO.getId());
<select id="selectByTelephone" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from user_info
where telephone = #{telephone,jdbcType=VARCHAR}
</select>
<!-- 根据id查找到加密的密码-->
<select id="selectByUserId" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from user_password
where user_id = #{userId,jdbcType=INTEGER}
</select>
至此登陆逻辑和代码到此结束