2、登录模块/login:get请求时,直接返回"/site/login"界面
只有是post请求提交时,调用service层的login方法,先验证验证码,再进行账号密码的认证;
同时,可以设置记住密码,生成一个UUID作为用户的登录凭证,将登录凭证添加过期时间,设置为10天,将loginTicket存入Redis中,将凭证返给controller层,将ticket和expiredSeconds传给cookie,以便拦截器使用。登录成功后,重定向到return“redirect:/index”首页。
4、退出登录/logout:service层在Redis中取出登录凭证,设置状态为1,再存进Redis。controller层重定向到登录页面。
---------------------------------------------------------------------------------------------------------------------------------
1.LoginTicketMapper:
package com.nowcoder.community.mapper;
import com.nowcoder.community.entity.LoginTicket;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
@Repository
public interface LoginTickerMapper {
LoginTicket selectByTicket(String ticket);
int insertLoginTicket(LoginTicket loginTicket);
int updateStatus(@Param("ticket") String ticket, @Param("status") int status);
}
2.LoginTicketMapper.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.nowcoder.community.mapper.LoginTickerMapper">
<select id="selectByTicket" resultType="LoginTicket">
select * from login_ticket where ticket=#{ticket};
</select>
<insert id="insertLoginTicket" parameterType="LoginTicket" keyProperty="id">
insert into login_ticket(user_id, ticket, status, expired) VALUES (#{userId},#{ticket},#{status},#{expired});
</insert>
<update id="updateStatus">
update login_ticket set status=#{status} where ticket=#{ticket};
</update>
</mapper>
3.UserService:
/**
* 登录功能
* @param username
* @param password
* @param expiredSeconds
* @return
*/
public Map<String,Object> login(String username,String password,Long expiredSeconds){
Map<String,Object> map=new HashMap<>();
//空值处理
if (StringUtils.isBlank(username)){
map.put("usernameMsg","账号不能为空!");
return map;
}
if (StringUtils.isBlank(password)){
map.put("passwordMsg","密码不能为空!");
return map;
}
//验证账号
User user = userMapper.selectByName(username);
if (user==null){
map.put("usernameMsg","该账号不存在!");
return map;
}
//验证状态
if (user.getStatus()==0){
map.put("usernameMsg","该账号未激活!");
return map;
}
//验证密码
password=CommunityUtil.md5(password+user.getSalt());
if (!user.getPassword().equals(password)){
map.put("passwordMsg","密码不正确!");
return map;
}
//生成登陆凭证
LoginTicket loginTicket = new LoginTicket();
loginTicket.setUserId(user.getId());
loginTicket.setTicket(CommunityUtil.generateUUID());
loginTicket.setStatus(0);
loginTicket.setExpired(new Date(System.currentTimeMillis()+expiredSeconds*1000L));
loginTickerMapper.insertLoginTicket(loginTicket);
map.put("ticket",loginTicket.getTicket());
return map;
}
/**
* 退出登录
* @param ticket
*/
public void logout(String ticket){
loginTickerMapper.updateStatus(ticket,1);
}
4.LoginCopntroller:
package com.nowcoder.community.controller;
import com.google.code.kaptcha.Producer;
import com.nowcoder.community.entity.User;
import com.nowcoder.community.service.UserServiceImpl;
import com.nowcoder.community.util.CommunityConstant;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import javax.imageio.ImageIO;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;
@Controller
public class LoginController implements CommunityConstant {
private static final Logger logger= LoggerFactory.getLogger(LoginController.class);
@Autowired
private UserServiceImpl userService;
@Autowired
@Qualifier("kaptchaProducer")
private Producer kaptchaProducer;
@Value("${server.servlet.context-path}")
private String contextPath;
@GetMapping("/register")
public String getRegisterPage(){
return "/site/register";
}
@GetMapping("/login")
public String getLoginPage(){
return "/site/login";
}
@PostMapping("/register")
public String register(Model model, User user){
Map<String,Object> map=userService.register(user);
if (map==null|| map.isEmpty()){
model.addAttribute("msg","注册成功,我们已经向您的邮箱发送了一封激活邮件,请尽快激活!");
model.addAttribute("target","/index");
return "/site/operate-result";
}else {
model.addAttribute("usernameMsg",map.get("usernameMsg"));
model.addAttribute("passwordMsg",map.get("passwordMsg"));
model.addAttribute("emailMsg",map.get("emailMsg"));
return "/site/register";
}
}
// http://localhost:8080/community/activation/101/code
@GetMapping("/activation/{userId}/{code}")
public String activation(Model model, @PathVariable("userId") int userId, @PathVariable("code") String code){
int result = userService.activation(userId, code);
if (result==ACTIVATION_SUCCESS){
model.addAttribute("msg","激活成功,您的帐号已经可以正常使用!");
model.addAttribute("target","/login");
}
else if (result==ACTIVATION_REPEAT){
model.addAttribute("msg","无效操作,该账号已经激活过!");
model.addAttribute("target","/index");
}
else {
model.addAttribute("msg","激活失败,您提供的激活码不正确!");
model.addAttribute("target","/index");
}
return "/site/operate-result";
}
@GetMapping("/kaptcha")
public void getKaptcha(HttpServletResponse response, HttpSession session){
//生成验证码
String text = kaptchaProducer.createText();
BufferedImage image = kaptchaProducer.createImage(text);
//将验证码存入Session
session.setAttribute("kaptcha",text);
//将图片输出给浏览器
response.setContentType("image/jpg");
try {
OutputStream stream = response.getOutputStream();
ImageIO.write(image,"jpg",stream);
} catch (IOException e) {
logger.error("响应验证码失败:"+e.getMessage());
}
}
@PostMapping("/login")
public String login(String username, String password, String code, boolean rememberme,
Model model,HttpSession session,HttpServletResponse response){
String kaptcha = (String) session.getAttribute("kaptcha");
//检查验证码
if (StringUtils.isBlank(kaptcha)||StringUtils.isBlank(code)||!kaptcha.equalsIgnoreCase(code)){
model.addAttribute("codeMsg","验证码不正确!");
return "/site/login";
}
//检查账号、密码
int expiredSeconds=rememberme ? REMMERBER_EXPIRED_SECONDS : DEFAULT_EXPIRE_SECONDS;
Map<String, Object> map= userService.login(username, password, (long) expiredSeconds);
if (map.containsKey("ticket")){
Cookie cookie = new Cookie("ticket", map.get("ticket").toString());
cookie.setPath(contextPath);
cookie.setMaxAge(expiredSeconds);
response.addCookie(cookie);
return "redirect:/index";
}
else {
model.addAttribute("usernameMsg",map.get("usernameMsg"));
model.addAttribute("passwordMsg",map.get("passwordMsg"));
return "/site/login";
}
}
@GetMapping("/logout")
public String logout(@CookieValue("ticket") String ticket){
userService.logout(ticket);
return "redirect:/login";
}
}