一直不知道邮箱验证是怎么一回事,一直觉得好神奇(因为本人几乎从来不用邮箱)在大佬的带领下还是成功实现了这个功能,话不多说开始操作:
我使用的技术:
java,maven,mysql,一部分相关依赖和jar包.
因为我使用的是QQ邮箱所以需要解锁一部分QQ邮箱的服务:
登录QQ邮箱,在设置->账户面板中开启POP3/SMTP服务:
注意!
这个服务开启之后会获取一个授权码千万不能丢,非常重要.
先讲一下流程吧
1.在注册页面填写信息,点击注册按钮.
2.后台controller接受到数据判断数据填写是否正确,如果正确保存用户数据并且用户为未激活状态.
3.发送邮件给用户,让用户激活账号.
4.用户激活成功后将用户的状态改为激活状态.
接下来开始代码的操作:
创建一个maven工程
这里我们需要一个JavaMail的坐标(其他坐标大家都不一样我就不放上来了)
<dependencies>
<!-- 我使用过的是1.5.0的版本 -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.5.0-b01</version>
<scope>compile</scope>
</dependency>
</dependencies>
还需要一个JavaMail的jar包放在共享模块中以供使用,以下是JavaMail代码:
public class MailUtil implements Runnable{
private String email;// 收件人邮箱
private String emailKey;// 激活码
public MailUtil(String email, String emailKey) {
this.email = email;
this.emailKey = emailKey;
}
@Override
public void run() {
// 1.创建连接对象javax.mail.Session
// 2.创建邮件对象 javax.mail.Message
// 3.发送一封激活邮件
String from = "你的QQ号@qq.com";// 发件人电子邮箱
String host = "smtp.qq.com"; // 指定发送邮件的主机smtp.qq.com(QQ)|smtp.163.com(网易)
Properties properties;// 获取系统属性
properties = System.getProperties();
properties.setProperty("mail.smtp.host", host);// 设置邮件服务器
properties.setProperty("mail.smtp.auth", "true");// 打开认证
try {
//QQ邮箱需要下面这段代码,163邮箱不需要
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
properties.put("mail.smtp.ssl.enable", "true");
properties.put("mail.smtp.ssl.socketFactory", sf);
// 1.获取默认session对象
Session session = Session.getDefaultInstance(properties, new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("你的QQ号@qq.com", "刚刚你激活的POP3激活码放这里"); // 发件人邮箱账号、授权码
}
});
// 2.创建邮件对象
Message message = new MimeMessage(session);
// 2.1设置发件人
message.setFrom(new InternetAddress(from));
// 2.2设置接收人
message.addRecipient(Message.RecipientType.TO, new InternetAddress(email));
// 2.3设置邮件主题
message.setSubject("账号激活");
// 2.4设置邮件内容
String content = "<html><head></head><body><h1>这是一封激活邮件,激活请点击以下链接</h1><h3><a href='http://localhost:8080/user/registerAllow?emailKey="
+ emailKey + "'>http://localhost:8080/user/registerAllow?emailKey=" + emailKey
+ "</href></h3></body></html>";
message.setContent(content, "text/html;charset=UTF-8");
// 3.发送邮件
Transport.send(message);
System.out.println("邮件成功发送!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
创建一个数据库表
用户
CREATE TABLE USER (
uid INT PRIMARY KEY AUTO_INCREMENT, #用户ID
username VARCHAR(50), #用户账号
PASSWORD VARCHAR(50), #用户密码
email VARCHAR(100), #电子邮件
emailKey VARCHAR(50), #生成的随机激活key
emailKeyTime INT, #邮箱激活有效验证时间
);
创建一个注册页面
基本上就这么多,然后我们回到后台:
我的controller层方法的代码(一共两个,第一个负责注册,第二个负责激活):
//注册
@PostMapping("/register")
public BaseResult register(@RequestBody User user){
if (user.getUsername().equals("") || user.getEmail().equals("")){
return BaseResult.error("数据填写不完整");
}
if(!user.getEmail().matches("^\\w+@(\\w+\\.)+\\w+$")){
return BaseResult.error("邮箱格式错误");
}
try {
userServiceImpl.register(user);
} catch (Exception e) {
e.printStackTrace();
return BaseResult.error(e.getMessage());
}
return BaseResult.ok("注册成功");
}
//激活
@GetMapping("/registerAllow")
public void emailBeUse(@RequestParam("emailKey") String emailKey){
//查找数据库查看是否能匹配到拥有该激活码的用户
try {
userServiceImpl.registerAllow(emailKey);
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
}
我的service层方法代码:
//注册
public void register(User user) {
//查找数据库,观察是否有相同的用户数据
User u = userDao.selectOne(user);
if (u != null){
//找到相同用户名,提示已注册.
throw new RuntimeException("用户名已注册");
}
//未注册用户需要生成邮箱激活码进行邮箱验证
String code = EmailUtils.getCode();
//保存用户到数据库,显示的是未激活用户
user.setState(0);
//存入激活码
user.setEmailKey(code);
//存入激活码有效时间(在方法里面我让他往后了十分钟)
user.setEmailKeyTime(EmailUtils.getKryEndTime());
try {
//储存用户
userDao.insert(user);
} catch (Exception e) {
//储存用户失败
e.printStackTrace();
}
//保存用户之后通过线程的方式给用户发送一封邮件
new Thread(new MailUtil(user.getEmail(),user.getEmailKey())).start();
}
//激活
public void registerAllow(String emailKey) {
//查询所有用户观察是否有匹配信息
User user = null;
user = userDao.selectWithEmailKey(emailKey);
if (user == null){
throw new RuntimeException("该用户没有注册,不存在激活码");
}else{
//找到了用户,还需要鉴别他的激活时间是否超时
Long emailKeyTime = user.getEmailKeyTime();
Long newTime = new Date().getTime();
if ((newTime - emailKeyTime) > (1000*60*10)){
//超时
throw new RuntimeException("用户激活码超时,请重新注册");
}else{
//激活成功修改用户状态
user.setState(1);
userDao.updateByPrimaryKey(user);
//跳转登录页面
}
}
}
我方法中的EmailUtils是用来生成激活码的一个工具类,用于生成激活码.
操作到这里基本已经结束了,具体细节还请大家自己动手解决.下面是图示解析:
数据库:
数据库:
激活完成
里面有一个小bug,就是邮件里面的链接如果打开了之后不可以正常发送,那么就复制链接到网页上粘到路径里面其实是可以正常使用链接去激活用户的.