简单实用的邮件任务 ,让验证码、激活链接来丰富你的登录注册
大家肯定遇到过很多下面的场景,当你在某个网站、某个APP注册信息的时候,为了验证身份,需要填写你的邮箱地址,之后邮箱可能会收到验证码,也可能会收到一个里面有激活链接的邮件,叫你点击链接进行激活。
就像下面这样:
这两种方式是登录注册时对邮件任务的经典应用场景。
那么今天就继续上次整合登录的讲解,人脸识别和三方登录,往期的文章已经介绍了,有兴趣的回头再去看看。
邮件任务
SpringBoot已经为我们整合了对发送邮件的支持,也就是说我们可以使用代码,很方便的给指定的邮箱发送任意内容的邮件。
整合步骤
引入邮件任务依赖
<!--引入邮件任务依赖-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId>
</dependency>
在SpringBoot的配置文件中配置邮件信息(以QQ邮箱为例)
spring: mail:username: 373675032@qq.compassword: ****************host: smtp.qq.comport: 465properties:mail:smtp:auth: truestarttls:enable: truerequired: truesocketFactory:port: 465class: javax.net.ssl.SSLSocketFactoryfallback: falsevalid: 5title: "用户验证"template: "您的动态验证码为:<strong style='color: red'>%s</strong>,%d分钟内有效,若非本人操作,请勿泄露。"
- username:发送方邮箱,也就是你的邮箱地址
- password:SMTP服务密码,并不是你的QQ密码
spring.mail.password通过下面方法获得
封装邮件服务类
/*** @author XUEW* @apiNote 邮件服务*/
@Service
public class EmailService {@Autowiredprivate JavaMailSenderImpl mailSender;/*** 发送方邮箱*/@Value("${spring.mail.username}")private String email;/*** 有效时长*/@Value("${spring.mail.valid}")private Integer valid;/*** 内容模版*/@Value("${spring.mail.template}")private String template;/*** 标题*/@Value("${spring.mail.title}")private String title;/*** 发送邮件验证码* @param targetEmail 目标邮箱* @return 验证码*/public String sendEmailCode(String targetEmail) {// 生成随机验证码String verifyCode = RandomUtil.randomNumbers(6);MimeMessage mimeMessage = mailSender.createMimeMessage();MimeMessageHelper helper = new MimeMessageHelper(mimeMessage);try {helper.setSubject(title);helper.setText(String.format(template, verifyCode, valid), true);helper.setFrom(email);helper.setTo(targetEmail);} catch (MessagingException e) {e.printStackTrace();}mailSender.send(mimeMessage);return verifyCode;}/*** 发送邮箱* @param targetEmail 目标邮箱* @param content 发送内容*/public void sendEmail(String targetEmail, String title, String content) {MimeMessage mimeMessage = mailSender.createMimeMessage();MimeMessageHelper helper = new MimeMessageHelper(mimeMessage);try {helper.setSubject(title);helper.setText(content, true);helper.setFrom(email);helper.setTo(targetEmail);} catch (MessagingException e) {e.printStackTrace();}mailSender.send(mimeMessage);}
}
邮件验证码的实现思路
操作步骤大家肯定都知道,输入完邮箱地址点击获取验证码后,按钮变成了disable状态,并且开始倒计时一分钟。
如此同时向后端发送异步请求,调用刚才写的邮件服务向输入的邮箱发送验证码。
/*** 发送邮箱验证码*/
@PostMapping("/sendEmailCode")
@ResponseBody
public ResponseResult sendEmailCode(String email, Map<String,Object> map, HttpSession session) {if (StrUtil.isEmpty(email)) {return ResponseResult.failure(500, "邮箱不能为空");}// 发送验证码String verifyCode = emailService.sendEmailCode(email);map.put("email", email);map.put("code", verifyCode);map.put("time", new Date());session.setAttribute("EMAIL_CODE" + email, map);return ResponseResult.success();
}
发送完成后,将验证码与邮箱缓存,这里可以使用session或者redis。
用户收到验证码后,填写后点击登录,后端服务开始进行一些列的校验工作,比如:缓存中是否存在此邮箱?验证码是否正确?验证码是否过期?诸如此类的操作。校验没问题,那么就可以进行入库保存等操作了。
/*** 验证码登录*/
@GetMapping("/loginEmail")
public String loginSms(String email, String code, HttpSession session) {Map<String,Object> codeData = (Map<String, Object>) session.getAttribute("EMAIL_CODE" + email);if (codeData == null) {throw new RuntimeException("登录失败:尚未发送验证码");}String sentCode = (String) codeData.get("code");Calendar calendar = Calendar.getInstance();calendar.setTime((Date) codeData.get("time"));calendar.add(Calendar.MINUTE, 5);if (System.currentTimeMillis() > calendar.getTime().getTime()) {session.removeAttribute("EMAIL_CODE" + email);throw new RuntimeException("登录失败:验证码已经超时");}if (!sentCode.equals(code)) {throw new RuntimeException("登录失败:验证码错误");}// 校验全部通过,执行入库等业务操作// ...return "redirect:/success";
}
邮件激活链接实现思路
那么激活链接是如何实现的呢?首先既然叫激活,那么说明用户的信息肯定是已经存入数据库了,只不过用户的状态是尚未激活,所以无法正常使用系统。那么点击激活链接,其实主要目的就是把用户的状态修改为正常,大家首先要明白这一点。
当用户注册完成后,默认状态为【未激活】,在入库之后,后端就需要给注册邮箱发送激活链接,那么激活链接如何设计呢?我给大家提供两个思路:
思路一
生成一串随机字符串叫做密钥,因为用户信息已经存库,所以用户ID我们也是可以获取到,之后将密钥和用户id缓存,同样可以使用session或者redis。
之后将密钥和用户id拼接成URL的参数,像下面这样:
http://localhost:8080/activate?uid=1&key=asjkdjflksdajflasdfjdlsfj
/*** 发送邮箱激活链接*/
@PostMapping("/sendEmailActivateUrl")
@ResponseBody
public ResponseResult sendEmailActivateUrl(Integer uid, HttpSession session) {// 前提条件:发送之前已经保存用户到数据库User user = userService.get(uid);String serverUrl = "http://localhost:8080";String key = RandomUtil.randomString(10);String content = String.format("点击此链接进行激活: <a href=\"%s/activate?uid=%d&key=%s\">点我激活</a>", serverUrl, uid, key);// 发送邮件emailService.sendEmail(user.getEmail(), "激活链接", content);// 存入缓存session.setAttribute("ACTIVATE" + uid, key);return ResponseResult.success();
}
注意在激活链接中访问的是activate
请求,路径传参数输入get方式,所以后端服务需要在controller中编写此服务用于激活用户。
/*** 用户激活* @param uid 用户ID* @param key 密钥* @return*/
@GetMapping("/activate")
public String activate(Integer uid, String key, HttpSession session) {User user = userService.get(uid);// 开始一系列校验if (Assert.isEmpty(user) ) {throw new RuntimeException("激活失败:尚未注册的用户");}if (user.getStatus() == 1) {throw new RuntimeException("激活失败:用户已完成激活");}// 获取激活信息String activateKey = (String) session.getAttribute("ACTIVATE" + uid);if (Assert.isEmpty(activateKey)) {throw new RuntimeException("激活失败:尚未发送激活邮件");}if (!activateKey.equals(key)) {throw new RuntimeException("激活失败:密钥匹配失败");}// 校验通过,更新用户状态// ...return "redirect:/success";
}
发送邮件的内容就可以是下面这样:
点击此链接进行激活: <a href="http://localhost:8080/activate?uid=1&key=asjkdjflksdajflasdfjdlsfj">点我激活</a>
收到的邮件如下:
思路二
和上面的区别主要在激活链接这块的设计,上面的可以实现,但是安全性和时效性上并不是很灵活和安全,所以我更推荐大家使用JWT Token的方式去作为激活链接的加密参数。
Token里面可以用来存放一些数据,并且可以很方便的设置Token的过期时间,这样我们在做校验的时候也会方便很多了。
所谓的JWT Token,也还是一串字符串,但是是混乱的,像下面这样:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImNpbmNvIiwicm9sZSI6ImFkbWluIiwic3ViIjoiYWRtaW4tdGVzdCIsImV4cCI6MTY0MjE0MDUyMCwianRpIjoiNDc0ZWRhNjUtYzI0Ny00OTg1LTgwNGEtMjM5NjliZjFhNDRhIn0.cRDXDjBmCMfgLCxNPINh_KBeKDPG-VNSA2LY95ySsmc
项目开源:https://github.com/373675032/login-system
简单实用的邮件任务 ,让验证码、激活链接来丰富你的登录注册相关推荐
- sql 拼接int类型的字段_一套简单实用的SQL脚本(下篇)
点击上方SQL数据库开发,关注获取SQL视频教程 SQL专栏 SQL数据库基础知识汇总 SQL数据库高级知识汇总 之前已经分享了一部分内容<一套简单实用的SQL脚本(上篇)>接上一章我们继 ...
- 一款简单实用的桌面电子邮件客户端
为大家分享一款Gmail 客户端,Mia for Gmail for mac运行在菜单栏,支持添加多个Gmail帐户,你可以快速搜索.阅读和撰写电子邮件,当你收到电子邮件时,Mia for Gmail ...
- html表格制作旅游网页,简单实用的网页表格特效_html
在我们制作主页的过程中,用到表格的地方非常多,灵活运用表格技巧可以为我们的网页增色不少,这里我就详细介绍几中特效表格的制作方法. 一.彩色虚线表格 .tab1 { border-top-width: ...
- 发邮件(通过发邮件 激活用户/激活链接)
POP3/SMTP服务 (如何使用 Foxmail 等软件收发邮件?) 已关闭 | 开启 IMAP/SMTP服务 (什么是 IMAP,它又是如何设置?) 已关闭 | 开启 Exchange服务 ( ...
- PS入门教程:简单实用的PS快捷键教程2
上篇内容从工具箱.文件操作.图层混合.选择功能.视图操作五方面入手分类总结了常用的PS快捷键教程.这篇内容小编再将从编辑操作.图像调整.加点按.取消操作这五方面为大家加码日常都可用到的PS快捷键教程. ...
- django自带邮件模块实现用户注册激活邮件发送
最近在看慕课网的利用Django搭建教学网站的视频,其中碰到了给注册用户发送激活邮件的问题.期间也遇到了一些小问题,在此记录一下. 实现邮件发送流程 利用django.core.mail模块下的sen ...
- windows 7重装系统(简单实用)
记录一个简单实用的windows系统重装的简易操作,也是为了下次自己使用方便.因为公司电脑是32位,而现在的主流是64以及某些软件要求使用64位,所以需要重新安装一下系统. 1 https://msd ...
- XP系统优化简单实用技法收藏
XP系统优化简单实用技法收藏 1.关闭计算机时自动结束任务: 在关机的时候,有时会弹出讨厌的对话框,提醒某个程序仍在运行,是否结束任务.其实完全梢酝ü坏愕阈薷娜肳indows自动结束这些仍在运行的程 ...
- 一个简单实用的,基于EF的三层架构
到底什么样的框架才是好框架呢?或许不同人有不同的看法.我个人觉一个好的框架,最重要的要是简单实用,能快速适开发,可维护性高(不会出现复制黏贴的代码),并能快速响应各种业务场景的变化的框架,同时性能不会 ...
最新文章
- Linux 线程属性的使用
- 快速完全删除node_modules
- 在控制台中实现“单词竞猜”游戏 C# 猜词游戏
- Mr.J-- 简单生日页面制作
- SQL SERVER2008 存储过程、表、视图、函数的权限
- Linux Shell编程 - 正则表达式
- 如何批量生成UPC-E条码
- CAN 通信协议(希望大家多多指点)
- python动态心形代码-python心形代码
- RTT移植STM32之创建进程
- 使用 RuPengGame游戏引擎包 建立游戏窗体 如鹏游戏引擎包下载地址 Thread Runnable 卖票实例...
- win7密码破解之“替换法”
- registry登录认证
- java 抓取搜狗微信_搜狗微信公众号文章抓取
- CentOs虚拟机硬盘扩容
- 2011年国内手机市场如何推演?
- Spring更简单的存储对象------不使用XML而使用注解
- 使用以太坊和 Metamask 再也不需要输入密码
- cnpm安装 指定版本_vue npm install安装某个指定版本的方法
- 江苏省计算机二级Python备考经验(2020年10月考试)