一、内容介绍
1.登录实现流程(单点登录):
2.实现项目中的注册接口
使用步骤:
1. 在common中引入依赖,复制jwt工具类:
点击查看代码jwt需要添加的依赖
<dependencies>
<!-- JWT-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
</dependency>
</dependencies>
2. 在common模块中创建JWT工具类
点击查看代码jwt的工具类
/*需要知道类中怎么去进行修改:*/
public class JwtUtils {
/*常量EXPIRE:设置token的过期时间
*APP_SECRET:密钥 (在公司中,一般是公司按照自己的加密规则生成) */
public static final long EXPIRE = 1000 * 60 * 60 * 24;
public static final String APP_SECRET = "ukc8BDbRigUDaY6pZFfWus2jZWLPHO";
/**
* 生成token字符串的方法
* @param id 用户id
* @param nickname 用户名称
* @return
*/
public static String getJwtToken(String id, String nickname){
String JwtToken = Jwts.builder() //构建jwt字符串
.setHeaderParam("typ", "JWT")
.setHeaderParam("alg", "HS256") //设置头信息
.setSubject("guli-user")
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + EXPIRE)) //设置过期时间 :一般修改时修改setSubject和EXPIRE
/*设置token的主体部分,也就是存储用户信息,如果有多个,可以添加多行*/
.claim("id", id)
.claim("nickname", nickname)
/*签名哈希:*/
.signWith(SignatureAlgorithm.HS256, APP_SECRET)
.compact();
return JwtToken;
}
/**
* 判断token是否存在与有效 :判断token是否是伪造的
* @param jwtToken
* @return
*/
public static boolean checkToken(String jwtToken) {
if(StringUtils.isEmpty(jwtToken)) return false;
try {
/*通过这行代码进行判断token值是否有效*/
Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 判断token是否存在与有效
* @param request 通过头信息,获取token 值
* @return
*/
public static boolean checkToken(HttpServletRequest request) {
try {
String jwtToken = request.getHeader("token");
if(StringUtils.isEmpty(jwtToken)) return false;
Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 根据token获取用户信息的id
* @param request
* @return
*/
public static String getMemberIdByJwtToken(HttpServletRequest request) {
String jwtToken = request.getHeader("token");
if(StringUtils.isEmpty(jwtToken)) return "";
Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
/*用来获取字符串中的主体部分:通过key 获取value */
Claims claims = claimsJws.getBody();
return (String)claims.get("id");
}
}
3.新建短信微服务
整合阿里云短信服务,注册时候发送手机验证码
- 在service 创建子模块 service_msm
- 创建包的结构,创建controller 和 service 等结构
- 阿里云短信服务开通和使用 SMS_259450133
- 编写代码实现短息的发送
- 在service-sms中引入依赖
短信服务模块添加的依赖
<dependencies>
<!-- 这是一个json的转化工具 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<!-- 阿里云操作的核心的库 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
</dependency>
</dependencies>
相关的配置application.properties
# 服务端口
server.port=8006
# 服务名
spring.application.name=service-msm
# mysql数据库连接
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/xiaofan_edu?serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123
#Redis 的相关配置
spring.redis.host=192.168.149.128
spring.redis.port=6379
spring.redis.database= 0
spring.redis.timeout=1800000
spring.redis.lettuce.pool.max-active=20
spring.redis.lettuce.pool.max-wait=-1
#最大阻塞等待时间(负数表示没限制)
spring.redis.lettuce.pool.max-idle=5
spring.redis.lettuce.pool.min-idle=0
#返回json的全局时间格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
#配置mapper xml文件的路径
mybatis-plus.mapper-locations=classpath:com/xiaofan/msmservice/mapper/xml/*.xml
#mybatis日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
设置生成随机数的工具类
/**
* 获取随机数的工具类
*/
public class RandomUtil {
private static final Random random = new Random();
private static final DecimalFormat fourdf = new DecimalFormat("0000");
private static final DecimalFormat sixdf = new DecimalFormat("000000");
public static String getFourBitRandom() {
return fourdf.format(random.nextInt(10000));
}
public static String getSixBitRandom() {
return sixdf.format(random.nextInt(1000000));
}
/**
* 给定数组,抽取n个数据
*
* @param list
* @param n
* @return
*/
public static ArrayList getRandom(List list, int n) {
Random random = new Random();
HashMap<Object, Object> hashMap = new HashMap<Object, Object>();
// 生成随机数字并存入HashMap
for (int i = 0; i < list.size(); i++) {
int number = random.nextInt(100) + 1;
hashMap.put(number, i);
}
// 从HashMap导入数组
Object[] robjs = hashMap.values().toArray();
ArrayList r = new ArrayList();
// 遍历数组并打印数据
for (int i = 0; i < n; i++) {
r.add(list.get((int) robjs[i]));
System.out.print(list.get((int) robjs[i]) + "\t");
}
System.out.print("\n");
return r;
}
}
编写Controller部分,里面实现了使用redis设置有效时常
@RestController
@RequestMapping("/eduservice/chapter")
@CrossOrigin //解决跨越问题
public class MsmController {
/*验证码在五分钟之内有效:怎么实现呢?
Redis能够设置过期时间,因此可以使用redis来进行设置它的有效时间
怎么做呢?
1.注入: private RedisTemplate<String,String> redisTemplate;
2.从Redis中获取验证码,如果能够获取到直接返回
3.如果获取不到,则进行阿里云短信发送
*/
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Autowired
private MsmService msmService;
@GetMapping("send/{phone}")
public R sendMsm(@PathVariable String phone) {
//2.从Redis中获取验证码,如果能够获取到直接返回
String code = redisTemplate.opsForValue().get(phone);
if (!StringUtils.isEmpty(code)) {
return R.ok();
}
//3.如果获取不到,则进行阿里云短信发送
//通过工具类,生成随机的数,传递给阿里云进行发送
String randomCode = RandomUtil.getFourBitRandom();//生成随机数
Map<String, Object> param = new HashMap<>();
param.put("code", randomCode);
//调用service中的方法进行短信的发送
boolean isSend = msmService.send(param, phone);
if (isSend) {
System.out.println(isSend + "---------------------------------");
//发送成功,把发送的验证码放到Redis中,并设置有效时间
//randomCode:这里需要传进来生成的随机数,如果传code ,则可能为空
redisTemplate.opsForValue().set(phone, randomCode, 5, TimeUnit.MINUTES);
return R.ok();
} else {
return R.error().message("短信发送失败");
}
}
}
生成service代码
public interface MsmService {
boolean send(Map<String, Object> param, String phone);
}
service 代码的实现类:在这里实现短信的发送功能
@Service
public class MsmServiceImpl implements MsmService {
/**
* 发送短信的方法:
*
* @param param 包含验证码
* @param phone 手机号
* @return 返回Boolean值,True 则发送成功
*/
@Override
public boolean send(Map<String, Object> param, String phone) {
if (StringUtils.isEmpty(phone)) return false; //判断电话是否为空
DefaultProfile profile =
DefaultProfile.getProfile("default", "LTAI5t5cpNhgU9e8PBo3nxqj", "VxmEJ1UnTi8jIwcPs1hd9vTlweyrz8");
IAcsClient client = new DefaultAcsClient(profile);
//设置一些相关的固定参数:
CommonRequest request = new CommonRequest();
//request.setProtocol(ProtocolType.HTTPS);
request.setMethod(MethodType.POST); //默认提交方式
request.setDomain("dysmsapi.aliyuncs.com");
request.setVersion("2017-05-25");
request.setAction("SendSms");
//设置发送相关的一些参数:
request.putQueryParameter("PhoneNumbers", phone); //设置发送的手机号
request.putQueryParameter("SignName", "阿里云短信测试"); //签名的名称
request.putQueryParameter("TemplateCode", "SMS_154950909"); //模板的Code
request.putQueryParameter("TemplateParam", JSONObject.toJSONString(param)); //设置验证码:JSON的格式
//最终的发送
try {
CommonResponse response = client.getCommonResponse(request);
System.out.println(response.getData());
return response.getHttpResponse().isSuccess();
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
e.printStackTrace();
}
return false;
}
}