Spring Boot郵箱連結註冊驗證
阿新 • • 發佈:2021-07-22
Spring Boot郵箱連結註冊驗證
簡單介紹
註冊流程
【1】前端提交註冊資訊
【2】後端接受資料
【3】後端生成一個UUID做為token,將token作為redis的key值,使用者資料作為redis的value值,並設定key的時長
【4】後端根據使用者資訊中的郵箱地址資訊,檢驗使用者是否已經註冊,如果沒有,生成註冊連結傳送到使用者郵箱,如果已經註冊,提示使用者該郵箱地址已被註冊
【5】使用者點選郵件中的註冊連結
【6】後端判斷redis中token是否過期,沒有將使用者資訊儲存到資料庫,提示使用者註冊成功
專案原始碼:https://gitee.com/residual-temperature/email-link-demo.git
郵箱效果圖
實現過程
1、pom檔案要加入的jar包
<!-- 郵件相關 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> <!-- redis相關 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
2、application.yml檔案中要加入的配置
spring:
redis:
host: # redis地址
port: 6379 # redis埠號(預設6379)
password: # redis密碼
mail:
host: smtp.qq.com # 郵箱協議
username: 地址 # 傳送的郵箱地址
password: 授權碼 # 郵箱的授權碼
3、定義實體類
@Repository @Data @AllArgsConstructor @NoArgsConstructor public class User implements Serializable { private long id; private String account; private String password; private String username; }
注意
此處沒有get(),set()方法是因為匯入了lombok包
4、redis的config配置
物件的儲存需要序列化,所以需要自定義RedisTemplete
@Configuration
public class RedisConfig {
//編寫自己的配置類
@Bean
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
//為了開發方便一般使用<String,Object>
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
//JSON序列化的配置
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
//String的序列化
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
//key採用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
//hash採用String的序列方式
template.setHashKeySerializer(stringRedisSerializer);
//value序列化採用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
//hash的Value序列化採用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
5、驗證連結生成和郵箱傳送的工具類CodeUtils的配置
@Component
public class CodeUtils {
@Resource
JavaMailSender mailSender;
@Resource
RedisTemplate<String, User> redisTemplate;
// 生成連結,並給接收的郵箱傳送郵件
public boolean sendCode(User user){
MimeMessage message = mailSender.createMimeMessage();
try{
MimeMessageHelper messageHelper = new MimeMessageHelper(message);
String token = UUID.randomUUID().toString(); // 生成UUID
redisTemplate.opsForValue().set(token,user);
redisTemplate.expire(token,300, TimeUnit.SECONDS);
messageHelper.setFrom("傳送方的郵箱地址"); //傳送方的郵箱地址,而不是接收方的郵箱地址
messageHelper.setTo(user.getAddress()); // 接收方的郵箱地址
messageHelper.setSubject("註冊"); // 郵箱標題
String html = "<html>\n" +
"<body>\n" +
"<p>請點選下方連結註冊</p>\n" +
"<a href=\"http://localhost:8081/lookCode/"+token+"\">http://localhost:8081/lookCode/"+token+"</a>" +
"</body>\n" +
"</html>";
messageHelper.setText(html,true); // 郵箱內容
mailSender.send(message); // 傳送郵箱
System.out.println("傳送成功");
return true;
}catch (Exception e){
System.out.println("傳送失敗");
return false;
}
}
// 判斷token是否過期
public boolean eqToken(String token){
return redisTemplate.hasKey(token);
}
// 根據token查詢使用者的資訊
public User findUser(String token){
return redisTemplate.opsForValue().get(token);
}
}
6、UserMapper的配置
@Mapper
@Repository
public interface UserMapper {
// 新增使用者 註解開發sql語句
@Insert("insert into user(account,password,username) values (#{account},#{password},#{username})")
public int addUser(User user);
}
7、UserService的配置
public interface UserService {
// 新增使用者
public boolean adduser(User user);
// 根據使用者註冊資訊進行註冊連結的的生成和傳送
public boolean sendCode(User user);
// 使用者點選註冊連結判斷token是否過期
public boolean eqToken(String token);
}
8、UserService的實現類UserServiceImpl的配置
@Service
public class UserServiceImpl implements UserService {
@Resource
UserMapper userMapper;
@Resource
CodeUtils codeUtils;
/**
* 添加註冊的使用者資訊
* @param user 註冊的使用者資訊
* @return 是否新增成功
*/
@Override
public boolean adduser(User user) {
return userMapper.addUser(user) > 0;
}
/**
* 生成連結和傳送連結
* @param address 接收的郵箱地址
* @param user 註冊的使用者資訊
*/
@Override
public boolean sendCode(User user) {
if ( codeUtils.sendCode(user)) // 呼叫驗證連結生成工具類中的生成連結和傳送郵件函式
return true;
else
return false;
}
/**
* 判斷token是否過期
* @param token 使用者註冊所接收的token
* @return 註冊成功與否
*/
@Override
public boolean eqToken(String token) {
boolean flag = codeUtils.eqToken(token);
if (flag){
User user = codeUtils.findUser(token);
adduser(user);
return true;
}else {
return false;
}
}
}
9、UserController的配置
@RestController
public class UserController {
@Resource
UserService userService;
// 根據使用者註冊資訊進行註冊連結的的生成和傳送
@PostMapping("/sendCode")
public Map<String,String> sendCode(@RequestBody User user){
boolean flag = userService.sendCode(user);
Map<String,String> map = new HashMap<>();
if (flag){
map.put("msg","郵件傳送成功,請前往您的郵箱進行註冊驗證");
return map;
}else {
map.put("msg","郵件傳送失敗");
return map;
}
}
// 判斷是否註冊成功
@GetMapping("/lookCode/{token}")
public Map<String,String> lookCode(@PathVariable("token")String token){
boolean flag = userService.eqToken(token);
Map<String,String> map = new HashMap<>();
if (flag){
map.put("msg","註冊成功");
/* 後續的操作 ... ...*/
return map;
}else {
map.put("msg","註冊碼過期,請重新註冊");
return map;
}
}
}
因為沒有寫前端頁面,所以就用postman和頁面來演示
postman測試
傳入user物件
返回結果
郵箱連結
點選註冊連結之後
註冊成功之後資料庫前後對比
註冊成功之前
註冊成功之後
總結
可能會遇到的問題
【1】有些內部網路不支援傳送郵箱,如果保證程式碼沒錯,可以換個網路試試
【2】如果是在本地測試,連線的是本地redis,記得開啟本地的redis