完成注册功能

This commit is contained in:
lu 2025-01-24 22:06:34 +08:00
parent cc7564b195
commit 67cd04f097
5 changed files with 88 additions and 27 deletions

View File

@ -5,6 +5,7 @@ import com.example.service.AuthorizeService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpSession;
import jakarta.validation.constraints.Pattern;
import org.hibernate.validator.constraints.Length;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -14,17 +15,32 @@ import org.springframework.web.bind.annotation.*;
public class AuthorizeController {
private final String EMAIL_REGEX = "^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$";
private final String USERNAME_REGEX = "^[a-zA-Z0-9\\u4e00-\\u9fa5]+$";
@Resource
AuthorizeService service;
@PostMapping("/valid-email")
public RestBean<String> validEmail(@Pattern(regexp = EMAIL_REGEX) @RequestParam("email") String email,
HttpSession session) {
if (service.sendValidateEmail(email,session.getId())) {
String s = service.sendValidateEmail(email, session.getId());
if (s == null) {
return RestBean.success("邮件已发送,请注意查收");
}else{
return RestBean.failure(400,"邮件发送失败请检查邮箱地址是否存在,如果还是失败请联系管理员");
return RestBean.failure(400,s);
}
}
@PostMapping("/register")
public RestBean<String> registerUser(@Pattern(regexp = USERNAME_REGEX) @Length(min = 2, max = 8) @RequestParam("username") String username,
@Length(min = 6,max = 16) @RequestParam("password") String password,
@Pattern(regexp = EMAIL_REGEX) @RequestParam("email") String email,
@Length(min = 6, max = 6) @RequestParam("code") String code,
HttpSession session) {
String s = service.validateAndRegister(username, password, email, code, session.getId());
if(s == null){
return RestBean.success("注册成功");
}else{
return RestBean.failure(400,s);
}
}
}

View File

@ -1,6 +1,7 @@
package com.example.mapper;
import com.example.entity.Account;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
@ -8,4 +9,7 @@ import org.apache.ibatis.annotations.Select;
public interface UserMapper {
@Select("select * from db_account where username = #{text} or email = #{text}")
Account findAccountByNameOrEmail(String text);
@Insert("insert into db_account (email, username, password) values (#{email}, #{username}, #{password})")
int createAccount(String email, String username, String password);
}

View File

@ -1,7 +1,9 @@
package com.example.service;
import com.example.entity.Account;
import org.springframework.security.core.userdetails.UserDetailsService;
public interface AuthorizeService extends UserDetailsService {
boolean sendValidateEmail(String email,String sessionId);
String sendValidateEmail(String email,String sessionId);
String validateAndRegister(String username, String password, String email, String code, String sessionID);
}

View File

@ -12,9 +12,9 @@ import org.springframework.mail.SimpleMailMessage;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import java.sql.Time;
import java.util.Optional;
import java.util.Random;
import java.util.concurrent.TimeUnit;
@ -34,6 +34,8 @@ public class AuthorizeServiceImpl implements AuthorizeService {
@Resource
StringRedisTemplate template;
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if(username == null){
@ -49,9 +51,6 @@ public class AuthorizeServiceImpl implements AuthorizeService {
.roles("user")
.build();
}
@Override
public boolean sendValidateEmail(String email, String sessionId) {
/**
* 1.先生成对应的验证码
* 2.把邮箱和对应的验证码直接放到Redis里面过期时间3分钟如果此时重新要求发送邮件
@ -60,11 +59,16 @@ public class AuthorizeServiceImpl implements AuthorizeService {
* 4.如果发送失败把redis里面的刚刚插入的删除
* 5.用户在注册时再从redis里面取出对应键值对然后看验证码是否一致
*/
@Override
public String sendValidateEmail(String email, String sessionId) {
String key = "email" + sessionId + ":" + email;
if(Boolean.TRUE.equals(template.hasKey(key))){
Long expire = Optional.ofNullable(template.getExpire(key, TimeUnit.SECONDS)).orElse(0L);
if(expire > 120)
return false;
return "请求频繁,请稍后再试";
}
if(mapper.findAccountByNameOrEmail(email) != null){
return "此邮箱以被注册";
}
Random random = new Random();
int code = random.nextInt(900000) + 100000;
@ -76,10 +80,31 @@ public class AuthorizeServiceImpl implements AuthorizeService {
try{
mailSender.send(message);
template.opsForValue().set(key, String.valueOf(code), 3, TimeUnit.MINUTES);
return true;
return null;
} catch (MailException e){
e.printStackTrace();
return false;
return "邮件发送失败,请检查邮箱地址是否有效";
}
}
@Override
public String validateAndRegister(String username, String password, String email, String code, String sessionId) {
String key = "email" + sessionId + ":" + email;
if(Boolean.TRUE.equals(template.hasKey(key))){
String s = template.opsForValue().get(key);
if(s == null)return "验证码失效,请重新获取";
if(s.equals(code)){
password = encoder.encode(password);
if (mapper.createAccount(email, username,password) > 0) {
return null;
}else{
return "内部错误,请联系管理员";
}
}else {
return "验证码错误,请检查后提交";
}
}else{
return "请先获取验证码验证邮箱";
}
}
}

View File

@ -54,6 +54,8 @@ const rules ={
const isEmailValid = ref(false)
const formRef = ref()
const coldTime = ref(0)
const onValidate = (prop, isValid) => {
if(prop === 'email')
isEmailValid.value = isValid
@ -61,7 +63,15 @@ const onValidate = (prop, isValid) => {
const register = () => {
formRef.value.validate((isValid) => {
if(isValid){
post('/api/auth/register',{
username: form.username,
password: form.password,
email: form.email,
code: form.code
}, (message) => {
ElMessage.success(message)
router.push('/')
})
}else{
ElMessage.warning('请完整填写注册信息!')
}
@ -73,8 +83,9 @@ const validateEmail = () => {
email: form.email
}, (message) => {
ElMessage.success(message)
}
)
coldTime.value = 60
setInterval( () => coldTime.value--, 1000)
})
}
</script>
@ -88,21 +99,21 @@ const validateEmail = () => {
<div style="margin-top: 50px">
<el-form :model="form" :rules="rules" @validate="onValidate" ref="formRef">
<el-form-item prop="username">
<el-input v-model="form.username" type="text" placeholder="用户名">
<el-input v-model="form.username" :maxlength="8" type="text" placeholder="用户名">
<template #prefix>
<el-icon><User /></el-icon>
</template>
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input v-model="form.password" type="password" placeholder="密码">
<el-input v-model="form.password" :maxlength="16" type="password" placeholder="密码">
<template #prefix>
<el-icon><Lock /></el-icon>
</template>
</el-input>
</el-form-item>
<el-form-item prop="password_repeat">
<el-input v-model="form.password_repeat" type="password" placeholder="重复密码">
<el-input v-model="form.password_repeat" :maxlength="16" type="password" placeholder="重复密码">
<template #prefix>
<el-icon><Lock /></el-icon>
</template>
@ -118,14 +129,17 @@ const validateEmail = () => {
<el-form-item prop="code">
<el-row :gutter="10">
<el-col :span="18">
<el-input v-model="form.code" type="text" placeholder="请输入验证码">
<el-input v-model="form.code" :maxlength="6" type="text" placeholder="请输入验证码">
<template #prefix>
<el-icon><EditPen /></el-icon>
</template>
</el-input>
</el-col>
<el-col :span="6">
<el-button style="width: 100%" @click="validateEmail" type="success" :disabled="!isEmailValid">获取验证码</el-button>
<el-button style="width: 100%" @click="validateEmail" type="success"
:disabled="!isEmailValid || coldTime > 0">
{{coldTime > 0 ? '请等待' + coldTime + '秒' : '获取验证码'}}
</el-button>
</el-col>
</el-row>
</el-form-item>