栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

用户登录模块Java后端实现

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

用户登录模块Java后端实现

 

目录

李Util工具

李Dao层(数据访问层:CRUD操作)

李Sevice层(业务逻辑层:条件判断)

李Controller层(控制层:接收请求、响应结果)


这里是CS大白话专场,让枯燥的学习变得有趣!

没有对象不要怕,我们new一个出来,每天对ta说不尽情话!

好记性不如烂键盘,自己总结不如收藏别人!

李Util工具
public interface CommunityConstant {
    
    // 默认的登录凭证超时时间 (12小时)
    int DEFAULT_EXPIRED_SECONDS = 3600 * 12;

    // “记住我”状态下凭证超时时间 (100天)
    int REMEMBER_EXPIRED_SECONDS = 3600 * 24 * 100;
}
public class CommunityUtil {

    
    public static String generateUUID() {
        // 去除生成的随机字符串中的 ”-“
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

    
    public static String md5(String key) {
        if (StringUtils.isBlank(key)) {
           return null;
        }
        return DigestUtils.md5DigestAsHex(key.getBytes());
    }

}
public class RedisKeyUtil {

    private static final String SPLIT = ":";
    private static final String PREFIX_KAPTCHA = "kaptcha"; // 验证码
    private static final String PREFIX_TICKET = "ticket"; // 登录凭证

     
    public static String getKaptchaKey(String owner) {
        return PREFIX_KAPTCHA + SPLIT + owner;
    }

    
    public static String getTicketKey(String ticket) {
        return PREFIX_TICKET + SPLIT + ticket;
    }

}

李Dao层(数据访问层:CRUD操作)

创建com.jodie.xxx.dao.UserMapper:

@Mapper
public interface UserMapper {
    
    User selectByName(String username);
}

在resources/mappers下创建user-mapper.xml写sql查询语句: 


    
        id, username, password, salt, email, type, status, activation_code, header_url, create_time
    
    
    

李Sevice层(业务逻辑层:条件判断)
@Service
public class UserService implements CommunityConstant {

    @Autowired
    private UserMapper userMapper;

     
    public Map login(String username, String password, int expiredSeconds) {
        Map 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包含用户id、登录凭证字符串ticket、是否有效、过期时间
        LoginTicket loginTicket = new LoginTicket();
        loginTicket.setUserId(user.getId());
        loginTicket.setTicket(CommunityUtil.generateUUID()); // 随机凭证
        loginTicket.setStatus(0); // 设置凭证状态为有效(当用户登出的时候,设置凭证状态为无效)
        loginTicket.setExpired(new Date(System.currentTimeMillis() + expiredSeconds * 1000)); // 设置凭证到期时间

        // 将登录凭证存入 redis
        String redisKey = RedisKeyUtil.getTicketKey(loginTicket.getTicket());
        // 自动把loginTicket序列化成一个json字符串
        redisTemplate.opsForValue().set(redisKey, loginTicket);

        map.put("ticket", loginTicket.getTicket());

        return map;
    }
}

李Controller层(控制层:接收请求、响应结果)

先随机生成当前页面暂时的用户id→cookie

随机生成验证码→redis

输入账号密码验证码,账号密码正确后,比较redis中的验证码与输入的code

验证码正确,登录成功,生成登录凭证ticket→redis/cookie

下次用户想免输入登录时,直接判断cookie中是否含有该用户ticket,有则直接登录,否则重新输入用户名和密码。

@Controller
public class LoginController implements CommunityConstant {

    private static final Logger logger = LoggerFactory.getLogger(LoginController.class);

    @Autowired
    private Producer kaptchaProducer;

    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${server.servlet.context-path}")
    private String contextPath;

    
    @GetMapping("/kaptcha")
    public void getKaptcha(HttpServletResponse response) {
        // 生成验证码
        String text = kaptchaProducer.createText(); // 生成随机字符
        System.out.println("验证码:" + text);
        BufferedImage image = kaptchaProducer.createImage(text); // 生成图片
        
        // 验证码的归属者
        String kaptchaOwner = CommunityUtil.generateUUID(); // 登录前随机生成用户暂时的id
        Cookie cookie = new Cookie("kaptchaOwner", kaptchaOwner); //将暂时id存入cookie中
        cookie.setMaxAge(60);
        cookie.setPath(contextPath);
        response.addCookie(cookie);
        // 将id对应的验证码存入 redis
        String redisKey = RedisKeyUtil.getKaptchaKey(kaptchaOwner);
        redisTemplate.opsForValue().set(redisKey, text, 60, TimeUnit.SECONDS);

        // 将图片输出给浏览器
        response.setContentType("image/png");
        try {
            ServletOutputStream os = response.getOutputStream();
            ImageIO.write(image, "png", os);
        } catch (IOException e) {
            logger.error("响应验证码失败", e.getMessage());
        }
    }

    
    @PostMapping("/login")
    public String login(@RequestParam("username") String username,
                        @RequestParam("password") String password,
                        @RequestParam("code") String code,
                        @RequestParam(value = "rememberMe", required = false) boolean rememberMe,
                        Model model, HttpServletResponse response,
                        @CookieValue("kaptchaOwner") String kaptchaOwner) {
        // 检查redis中id对应的验证码
        String kaptcha = null;
        if (StringUtils.isNotBlank(kaptchaOwner)) {
            String redisKey = RedisKeyUtil.getKaptchaKey(kaptchaOwner);
            kaptcha = (String) redisTemplate.opsForValue().get(redisKey);
        }
       // 判断redis中的验证码是否和输入的验证码code一致
        if (StringUtils.isBlank(kaptcha) || StringUtils.isBlank(code) || !kaptcha.equalsIgnoreCase(code)) {
            model.addAttribute("codeMsg", "验证码错误");
            return "/site/login";
        }

        // 凭证过期时间(是否记住我)
        int expiredSeconds = rememberMe ? REMEMBER_EXPIRED_SECONDS : DEFAULT_EXPIRED_SECONDS;
        // 验证用户名和密码
        Map map = userService.login(username, password, expiredSeconds);
        if (map.containsKey("ticket")) {
            // 账号和密码均正确,则服务端会生成 ticket,浏览器通过 cookie 存储 ticket
            Cookie cookie = new Cookie("ticket", map.get("ticket").toString());
            cookie.setPath(contextPath); // cookie有效范围
            cookie.setMaxAge(expiredSeconds); //cookie存在时间
            response.addCookie(cookie); // 服务器返回给浏览器cookie以便下次判断
            return "redirect:/index"; // 重定向
        }
        else {
            model.addAttribute("usernameMsg", map.get("usernameMsg"));
            model.addAttribute("passwordMsg", map.get("passwordMsg"));
            return "/site/login";
        }
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1020386.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号