目录
一、短信发送
1.1 阿里云短信服务
1.1.1 设置短信签名
1.1.2 模板管理
1.1.3 设置AccessKey
1.2 短信发送——代码开发
1.2.1 导入maven坐标
1.2.2 调用API
1.2 手机验证码登录
1.2.1 用户数据库表
1.2.2 修改过滤器
1.2.3 随机生成验证码的工具类
1.2.4 手机验证码登录-- 发送验证码
1.2.5 手机验证码登录-- 验证验证码
一、短信发送
1.1 阿里云短信服务
短信服务_企业短信营销推广_验证码通知-阿里云
也可以在下面这个地方查看短信服务
1.1.1 设置短信签名
短信签名就是短信发送者的署名,表示发送方的身份
1.1.2 模板管理
申请下来之后可以点击详情进行查看
其中模板CODE是自动生成的,不用管,重点是模板的内容
1.1.3 设置AccessKey
创建新的用户
勾选上之后,我们在编程代码中就能使用
当我们创建用户成功后,就生成了一对AccessKey,即AccessKey ID(用户名) 与AccessKey Secret(密码)
很多人在这里的时候不小心没截图或者没保存就关了,丢失了AccessKey,但是不要紧,还可以再次创建
还有就是如果别人知道了我们的AccessKey,那别人使用的时候会就花我们的钱。我们也可以把泄露的AccessKey禁用
之后再新增授权。这次授权的意思就是仅仅授予有关短信服务的,即是我们泄露了,别人也只能操作短信服务,对我们的影响很小。
1.2 短信发送——代码开发
参照官方文档即可
新手指引_短信服务-阿里云帮助中心
1.2.1 导入maven坐标
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.5.16</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>2.1.0</version>
</dependency>
1.2.2 调用API
/**
* 短信发送工具类
*/
public class SMSUtils {
/**
* 发送短信
* @param signName 签名
* @param templateCode 模板
* @param phoneNumbers 手机号
* @param param 参数
*/
public static void sendMessage(String signName, String templateCode,String phoneNumbers,String param){
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "LTAI5tHRxs2FeCu5JcJTGbm2", "v0H4PaJpXSwNr6XChtlVYAgmQWgKRA");
IAcsClient client = new DefaultAcsClient(profile);
SendSmsRequest request = new SendSmsRequest();
request.setSysRegionId("cn-hangzhou");
// 要发送给那个人的电话号码
request.setPhoneNumbers(phoneNumbers);
// 我们在阿里云设置的签名
request.setSignName(signName);
// 我们在阿里云设置的模板
request.setTemplateCode(templateCode);
// 在设置模板的时候有一个占位符
request.setTemplateParam("{\"code\":\""+param+"\"}");
// request.setPhoneNumbers("1368846****");//接收短信的手机号码
// request.setSignName("阿里云");//短信签名名称
// request.setTemplateCode("SMS_20933****");//短信模板CODE
// request.setTemplateParam("张三");//短信模板变量对应的实际值
try {
SendSmsResponse response = client.getAcsResponse(request);
System.out.println("短信发送成功");
}catch (ClientException e) {
e.printStackTrace();
}
}
}
1.2 手机验证码登录
- 方便、快捷、无需注册、直接登陆
- 使用短信验证码作为登录凭证,无序记忆密码
- 安全
登录流程: 输入手机号 -> 获取验证码 -> 输入验证码 -> 点击登录 -> 登陆成功
注意: 通过手机验证码登录,手机号是区分不同用户的标识
1.2.1 用户数据库表
因为是通过手机和验证码登录的,所以没有用户名和密码字段
1.2.2 修改过滤器
在写代码之前记得要在过滤器中定义不需要处理的请求路径/user/sendMsg和/user/login
然后访问路径: http://localhost:8080/front/page/login.html
/**
* 检查用户是否已经完成登录
* 过滤器与拦截器的区别:Filter对所有访问进行增强(在Tomcat服务器进行配置),Interceptor仅针对SpringMVC的访问进行增强
*/
@Slf4j
@WebFilter(filterName = "loginCheckFilter", urlPatterns = "/*") //urlPatterns指定拦截哪些路径
public class LoginCheckFilter implements Filter {
// 此对象的作用:路径匹配器, 匹配路径时支持通配符
public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// servletRequest向下强制类型转换
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//1. 获取本次请求的URI( URI:请求的资源路径)
String requestURI = request.getRequestURI();
log.info("拦截到请求:{}", request.getRequestURI());
// 定义不用处理的请求路径
String[] urls = new String[]{
"/employee/login",
"/employee/logout",
"/backend/**",
"/front/**",
"/common/**",
"/user/sendMsg",
"/user/login"
};
//2. 判断本次请求是否需要处理(因为有些请求并不需要用户登录)
boolean check = check(requestURI, urls);
//3.如果不需要处理,则直接放行
if (check) {
log.info("本次请求{}不需要处理", request.getRequestURI());
filterChain.doFilter(request, response);
return;
}
//4-1.判断登录状态,如果已登录,则直接放行.从session中获取用户,如果获取到说明已经登录
if (request.getSession().getAttribute("employee") != null) {
log.info("用户已登录,用户id为{}", request.getSession().getAttribute("employee"));
Long empId = (Long) request.getSession().getAttribute("employee");
BaseContext.setCurrentId(empId);
filterChain.doFilter(request, response);
return;
}
//4-2.判断登录状态,如果已登录,则直接放行.从session中获取用户,如果获取到说明已经登录
if (request.getSession().getAttribute("user") != null) {
log.info("用户已登录,用户id为{}", request.getSession().getAttribute("user"));
Long userId = (Long) request.getSession().getAttribute("user");
BaseContext.setCurrentId(userId);
filterChain.doFilter(request, response);
return;
}
//5.如果未登录则返回未登录结果
log.info("资源路径路径:{},用户未登录{}", request.getRequestURI(), request.getSession().getAttribute("employee"));
// 通过输出流的方式向客户端响应数据 (为什么要返回这个NOTLOGIN? 因为前端需要这个来进行判定是否登录)
response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
// filterChain.doFilter(request, response); 加上这个就无法实现
}
/**
* 检查本次请求是否需要放行
*
* @param requestURI 请求的资源路径
* @param urls 放过的路径
* @return true 放行
*/
public boolean check(String requestURI, String[] urls) {
for (String url : urls) {
boolean match = PATH_MATCHER.match(url, requestURI);
if (match) {
// 放行
return true;
}
}
return false;
}
}
1.2.3 随机生成验证码的工具类
/**
* 随机生成验证码工具类
*/
public class ValidateCodeUtils {
/**
* 随机生成验证码
* @param length 长度为4位或者6位
* @return
*/
public static Integer generateValidateCode(int length){
Integer code =null;
// 长度为4
if(length == 4){
code = new Random().nextInt(9999);//生成随机数,最大为9999
if(code < 1000){
code = code + 1000;//保证随机数为4位数字
}
// 长度为6
}else if(length == 6){
code = new Random().nextInt(999999);//生成随机数,最大为999999
if(code < 100000){
code = code + 100000;//保证随机数为6位数字
}
// 其他情况
}else{
throw new RuntimeException("只能生成4位或6位数字验证码");
}
return code;
}
/**
* 随机生成指定长度字符串验证码
* @param length 长度
* @return
*/
public static String generateValidateCode4String(int length){
Random rdm = new Random();
String hash1 = Integer.toHexString(rdm.nextInt());
String capstr = hash1.substring(0, length);
return capstr;
}
}
1.2.4 手机验证码登录-- 发送验证码
两次ajax请求:
1. 登录页面输入手机号,点击【获取验证码】按钮,页面发送ajax请求,在服务端调用短信服务API给指定手机号发送验证码短信文章来源:https://www.toymoban.com/news/detail-421301.html
2. 在登录页面输入验证码,点击【登录】按钮,发送ajax请求,在服务端处理登录请求文章来源地址https://www.toymoban.com/news/detail-421301.html
@PostMapping("/sendMsg")
public R<String> sendMsg(@RequestBody User user, HttpSession session){
// 1.获取手机号
String phone = user.getPhone();
if(StringUtils.isEmpty(phone)){
return R.error("短信发送失败");
}
// 2.随机生成四位验证码
String code = ValidateCodeUtils.generateValidateCode(4).toString();
// 3.调用阿里云提供的短信服务
SMSUtils.sendMessage("张靖奇","",phone,code);
// 4.需要将生成的验证码保存到session中
session.setAttribute(phone,code);
return R.success("验证码短信发送成功");
}
1.2.5 手机验证码登录-- 验证验证码
// 其实传过来的phone:xxxx,code:xxx 也可以用map集合接收
@PostMapping("/login")
public R<User> login(@RequestBody Map map, HttpSession session) {
log.info(map.toString());
// 1. 获取手机号
String phone = map.get("phone").toString();
// 2. 获取验证码
String code = map.get("code").toString();
// 3. 从Session中获取保存的验证码
Object codeInSession = session.getAttribute(phone);
// 4. 进行验证码比对(页面提交的验证码和Session中保存的验证码比对)
if (codeInSession != null && codeInSession.equals(code)) {
// 5.对比成功,说明登录成功
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(User::getPhone,phone);
User user = userService.getOne(queryWrapper);
if (user==null){
// 6. 如果新用户,自动注册
user = new User();
user.setPhone(phone);
user.setStatus(1);
userService.save(user);
}
session.setAttribute("user",user.getId());
return R.success(user);
}
return R.error("登录失败");
}
到了这里,关于SpringBoot——短信发送、手机验证码登录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!