Springboot搭建简易论坛4
2020-10-26 本文已影响0人
charmingBueaty
五、登录模块
注册成功之后肯定是要进行登录了
- 添加登录相关接口
- UserService.class添加login接口
/**
* 用户登录
* @param telephone 手机号
* @param password 密码
* @return 向数据库查询的结果条数
*/
UserDao login(String telephone, String password) throws BusinessException;
- UserPasswordDaoMapper.class添加通过用户id获取密码的接口方法(之前使用了用户信息和用户密码分表存储的方式)
UserPasswordDao selectByUserId(Integer id);
- UserPasswordDaoMapper.xml添加对应的mybatis方法
<select id="selectByUserId" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from user_pwd
where user_id = #{id,jdbcType=INTEGER}
</select>
- UserServiceImpl.class实现login接口方法
@Override
public UserDao login(String telephone, String password) throws BusinessException {
UserDao userDao = userDaoMapper.selectByTelephone(telephone);
if (userDao == null) {
throw new BusinessException(EmBusinessError.USER_LOGIN_ERROR);
}
UserPasswordDao passwordDao = userPasswordDaoMapper.selectByUserId(userDao.getId());
if (StringUtils.equals(passwordDao.getUserPassword(), password)) {
throw new BusinessException(EmBusinessError.USER_LOGIN_ERROR);
}
return userDao;
}
- 添加登录验证码,此处使用谷歌的kaptcha
在pom.xml文件中添加如下依赖
<!-- Google Kaptcha -->
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
- 新建utils包,用来存放项目中使用的工具类,创建验证码配置类和验证码生成类
KaptchaConfig.java
import java.util.Properties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
/**
* @author Administrator
* @create 2020 -10 -21 9:43
*/
@Component
public class KaptchaConfig {
@Bean
public DefaultKaptcha getDefaultKaptcha() {
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
Properties properties = new Properties();
// 图片边框
properties.setProperty("kaptcha.border", "no");
// 字体颜色
properties.setProperty("kaptcha.textproducer.font.color", "red");
// 图片宽
properties.setProperty("kaptcha.image.width", "110");
// 图片高
properties.setProperty("kaptcha.image.height", "40");
// 字体大小
properties.setProperty("kaptcha.textproducer.font.size", "30");
// session key
properties.setProperty("kaptcha.session.key", "code");
// 验证码长度
properties.setProperty("kaptcha.textproducer.char.length", "4");
// 字体
properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑");
properties.setProperty("kaptcha.noise.color", "35,37,38");
Config config = new Config(properties);
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
}
VerifyCode.java
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;
/**
* @author Administrator
* @create 2020 -10 -20 16:33
*/
public class VerifyCode {
public static String drawRandomText(int width, int height, BufferedImage verifyImg) {
Graphics2D graphics = (Graphics2D) verifyImg.getGraphics();
//设置画笔颜色-验证码背景色
graphics.setColor(Color.WHITE);
//填充背景
graphics.fillRect(0, 0, width, height);
graphics.setFont(new Font("微软雅黑", Font.BOLD, 40));
//数字和字母的组合
String baseNumLetter = "123456789abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ";
StringBuffer sBuffer = new StringBuffer();
//旋转原点的 x 坐标
int x = 10;
String ch = "";
Random random = new Random();
for (int i = 0; i < 4; i++) {
graphics.setColor(getRandomColor());
//设置字体旋转角度
//角度小于30度
int degree = random.nextInt() % 30;
int dot = random.nextInt(baseNumLetter.length());
ch = baseNumLetter.charAt(dot) + "";
sBuffer.append(ch);
//正向旋转
graphics.rotate(degree * Math.PI / 180, x, 45);
graphics.drawString(ch, x, 45);
//反向旋转
graphics.rotate(-degree * Math.PI / 180, x, 45);
x += 48;
}
//画干扰线
for (int i = 0; i < 6; i++) {
// 设置随机颜色
graphics.setColor(getRandomColor());
// 随机画线
graphics.drawLine(random.nextInt(width), random.nextInt(height),
random.nextInt(width), random.nextInt(height));
}
//添加噪点
for (int i = 0; i < 30; i++) {
int x1 = random.nextInt(width);
int y1 = random.nextInt(height);
graphics.setColor(getRandomColor());
graphics.fillRect(x1, y1, 2, 2);
}
return sBuffer.toString();
}
/**
* 随机取色
*/
private static Color getRandomColor() {
Random ran = new Random();
return new Color(ran.nextInt(256),
ran.nextInt(256), ran.nextInt(256));
}
}
说明:这两个文件都是关于登陆时所使用的验证码相关配置文件,可以根据自己的需求修改相关配置来获取自己想要的验证码样式。
- UserControler.class 添加验证码输出控制器方法getVerifyCode()
// 注入验证码对象
@Resource
DefaultKaptcha defaultKaptcha;
@GetMapping("/getVerifyCode")
public void getVerifyCode(HttpServletResponse httpServletResponse)
throws Exception {
byte[] captchaChallengeAsJpeg = null;
ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
try {
// 生产验证码字符串并保存到session中
String createText = defaultKaptcha.createText();
httpServletRequest.getSession().setAttribute("verificationCode", createText);
// 使用生成的验证码字符串返回一个BufferedImage对象并转为byte写入到byte数组中
BufferedImage challenge = defaultKaptcha.createImage(createText);
ImageIO.write(challenge, "jpg", jpegOutputStream);
} catch (IllegalArgumentException e) {
httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
// 定义response输出类型为image/jpeg类型,使用response输出流输出图片的byte数组
captchaChallengeAsJpeg = jpegOutputStream.toByteArray();
httpServletResponse.setHeader("Cache-Control", "no-store");
httpServletResponse.setHeader("Pragma", "no-cache");
httpServletResponse.setDateHeader("Expires", 0);
httpServletResponse.setContentType("image/jpeg");
ServletOutputStream responseOutputStream = httpServletResponse.getOutputStream();
responseOutputStream.write(captchaChallengeAsJpeg);
responseOutputStream.flush();
responseOutputStream.close();
}
- UserController.class添加处理登录的控制器方法login()
@RequestMapping("/login")
public CommonReturnType login(@RequestParam(name = "telephone") String telephone,
@RequestParam(name = "password") String password,
@RequestParam(name = "code") String code) throws BusinessException, NoSuchAlgorithmException {
// 校验验证码,使用阿里巴巴德鲁伊包中的StringUtils类中的equals方法进行比较
String sessionCode = "verificationCode";
if (!StringUtils.equals(code, (String) httpServletRequest.getSession().getAttribute(sessionCode))) {
throw new BusinessException(EmBusinessError.PARAMETER_INVALID, "验证码错误");
}
UserDao userDao = userService.login(telephone, encodeByMd5(password));
if (userDao.getStatus() == USER_STATUS_BAN) {
throw new BusinessException(EmBusinessError.USER_LOGIN_ERROR, "您的账号已被禁用,请联系管理员!");
}
if (userDao.getStatus() == USER_STATUS_ALLOW) {
// 使用session记录账号的登录状态
httpServletRequest.getSession().setAttribute("isLogin", true);
httpServletRequest.getSession().setAttribute("loginUser", userDao);
}
return CommonReturnType.create(userDao);
}
总结:目前的登录模块相对简单只是功能的实现