一:认证服务环境搭建
1.新建gulimail-auth-server
2.整合相关依赖
<!--引入commom依赖-->
<dependency>
<groupId>com.sysg.gulimail</groupId>
<artifactId>gulimail-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!--排除掉数据库相关依赖-->
<exclusions>
<exclusion>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
3.将gulimail-auth-server配置进nacos
1)在application.properties配置文件中配置
spring.application.name=gulimail-auth-server
spring.cloud.nacos.discovery.server-sddr=127.0.0.1:8848
server.port=20000
2)在主启动类添加注解
//开启服务注册发现功能
@EnableDiscoveryClient
//开启服务远程调用功能
@EnableFeignClients
3)开启服务
4.导入登录注册页面
将静态资源放到nginx里面,实现动静分离
5.配置网关
- id: gulimail_auth_route
uri: lb://gulimail-auth-server
predicates:
- Host=auth.gulimail.com
二:springMVC映射请求到页面
1.新建config
@Configuration
/**
* 页面跳转控制类
*/
public class GulimailWebConfig implements WebMvcConfigurer {
/**
* 视图映射
* @param registry
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login.html").setViewName("login");
registry.addViewController("/reg.html").setViewName("reg");
}
}
三:验证码倒计时
1.点击验证码,进入60秒倒计时
<a id="sendCode">发送验证码</a>
$(function () {
$("#sendCode").click(function () {
/**
* 1.给指定手机发送验证码
* 2.添加验证码倒计时功能
*/
//判断有没有正在进行倒计时操作
if($(this).hasClass("disabled")){
//正在倒计时
} else {
//给指定的手机发送验证码
let phone = $("#phoneNumber").val();
$.get("/sms/controller?phone="+phone);
timeoutChangeStyle();
}
});
});
let num = 60;
function timeoutChangeStyle(){
$("#sendCode").attr("class","disabled");
if( num == 0){
$("#sendCode").text("发送验证码");
num = 60;
$("#sendCode").attr("class","");
} else {
let str = num+"s 后再次发送";
$("#sendCode").text(str);
setTimeout("timeoutChangeStyle()",1000);
}
num--;
}
四:阿里云配置发送短信验证码
1.登陆阿里云,购买0元五次套餐
2.短信验证码接口
调用地址:http(s)://dfsns.market.alicloudapi.com/data/send_sms
请求方式:POST
返回类型:JSON
3.代码实现
package com.sysg.gulimail.thirdparty.component;
import com.sysg.gulimail.thirdparty.util.HttpUtils;
import lombok.Data;
import org.apache.http.HttpResponse;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Data
@Component
@ConfigurationProperties(prefix = "spring.cloud.alicloud.sms")
public class SmsCpmponent {
private String host;
private String path;
private String templateId;
private String appcode;
public void sendSmsCode(String phone,String code){
String method = "POST";
Map<String, String> headers = new HashMap<String, String>();
//最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
headers.put("Authorization", "APPCODE " + appcode);
//根据API的要求,定义相对应的Content-Type
headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
Map<String, String> querys = new HashMap<String, String>();
Map<String, String> bodys = new HashMap<String, String>();
bodys.put("content", "code:"+code);
bodys.put("phone_number", phone);
bodys.put("template_id", templateId);
try {
HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
System.out.println(response.toString());
//获取response的body
//System.out.println(EntityUtils.toString(response.getEntity()));
} catch (Exception e) {
e.printStackTrace();
}
}
}
- host;path;templateId;appcode等参数动态配置
- @ConfigurationProperties(prefix = “spring.alicloud”)将配置信息绑定到配置文件
#数据源
spring:
cloud:
#nacos地址
nacos:
discovery:
server-addr: 127.0.0.1:8848
#阿里云的子系统用户名和密码
alicloud:
access-key: LTAIfwfwfwewefewfoZ5dh
secret-key: disClqm4wefwefewff
oss:
endpoint: osfwefwef.com
bucket: gulimail-sysg
sms:
host: https://dfsns.market.alicloudapi.com
path: /data/send_sms
templateId: TPL_0000
appcode: 712wefwefweab39a78
#服务的名称,用于让nacos知道那个服务正在被调用
application:
name: gulimail-third-party
#端口
server:
port: 30000
4.本地调试
1)引入httpUtil依赖
https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/src/main/java/com/aliyun/api/gateway/demo/util/HttpUtils.java
2)引入processor依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
3)测试成功
五:短信验证码后台接口
1.新建SmsSendController,用来处理短信验证码发送功能
@RestController
@RequestMapping("/sms")
public class SmsSendController {
@Autowired
private SmsComponent smsComponent;
/**
* 提供给别的服务进行调用
* @param phone
* @param code
* @return
*/
@GetMapping("/sendcode")
public R sendCode(@RequestParam("phone") String phone, @RequestParam("code")String code){
smsComponent.sendSmsCode(phone,code);
return R.ok();
}
}
2.在auth模块远程调用短信验证码功能
1)新建ThirdPartFeignService
@FeignClient("gulimail-third-party")
public interface ThirdPartFeignService {
@GetMapping("/sms/sendcode")
public R sendCode(@RequestParam("phone") String phone, @RequestParam("code")String code);
}
2)随机生成六位随机数字
/**
* 生成随机数
*/
public class RandomUUID {
/**
* 生成六位数字随机数
* @return
*/
public static String randomSixNumber(){
StringBuilder str = new StringBuilder();
Random random = new Random();
for (int i = 0; i < 6 ; i++) {
//随机生成10以内的数字
int number = random.nextInt(10);
str.append(number);
}
return str.toString();
}
}
3)添加发送验证码功能
@Controller
public class LoginController {
@Autowired
private ThirdPartFeignService thirdPartFeignService;
@GetMapping("/sms/sendcode")
public R sendCode(@RequestParam("phone") String phone){
//随机生成验证码
String code = RandomUUID.randomSixNumber();
thirdPartFeignService.sendCode(phone,code);
return R.ok();
}
}
注:随机生成的验证码就是发送到你手机上的验证码
3.测试发送短信验证码
//给指定的手机发送验证码
let phone = $("#phoneNumber").val();
$.get("/sms/sendcode?phone="+phone);
发送成功
思考:如果刷新页面后,再次获取验证码,就会重置60秒,所以验证码的60s必须是严格意义上的60s。并且需要给验证码设置超时时间。
六:验证码防刷校验,设置过期时间
1)给auth模块引入redis依赖
<!--引入redis依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2)配置redis地址
spring.redis.host=127.0.0.1
spring.redis.port=6379
3)存储到redis中。key-phone,value-code
@GetMapping("/sms/sendcode")
@ResponseBody
public R sendCode(@RequestParam("phone") String phone){
//1.接口防刷,防止同一个手机号60s内再次发送
String redisCode = stringRedisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + phone);
if(!StringUtils.isEmpty(redisCode)){
long redisDate = Long.parseLong(redisCode.split("_")[1]);
if(System.currentTimeMillis() - redisDate < 60000){
//60秒内不可以再发
return R.error(BizCodeEnume.SMS_CODE_EXCEPTION.getCode(),BizCodeEnume.SMS_CODE_EXCEPTION.getMsg());
}
}
//随机生成验证码
String code = RandomUUID.randomSixNumber();
String dateCode = code + "_" + System.currentTimeMillis();
//2.验证码的再次校验,存储到redis中。key-phone,value-code
//key——"sms:code:15648961564" value-564986
//保存到redis里面,并设置10分钟超时时间
stringRedisTemplate.opsForValue().set(AuthServerConstant.SMS_CODE_CACHE_PREFIX + phone,dateCode,10, TimeUnit.MINUTES);
thirdPartFeignService.sendCode(phone,code);
return R.ok();
}
- key-phone,value-code
- key-“sms:code:15648961564” value-564986