Commit 8f3ce704 by 段启岩

新增:邮箱注册,邮箱激活,修改密码登录为账号登录

parent 92c0430f
...@@ -128,6 +128,11 @@ ...@@ -128,6 +128,11 @@
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope> <scope>test</scope>
<exclusions> <exclusions>
......
package cn.meteor.beyondclouds.common.exception; package cn.meteor.beyondclouds.common.exception;
import cn.meteor.beyondclouds.core.IErrorCode;
import cn.meteor.beyondclouds.core.exception.ServiceException;
/** /**
* @author meteor * @author meteor
*/ */
public class RedisOperationException extends Exception { public class RedisOperationException extends RuntimeException {
public RedisOperationException() { public RedisOperationException() {
} }
......
...@@ -6,10 +6,20 @@ package cn.meteor.beyondclouds.core.redis; ...@@ -6,10 +6,20 @@ package cn.meteor.beyondclouds.core.redis;
*/ */
public final class RedisKey { public final class RedisKey {
private static final String VERIFY_CODE_KEY_PREFIX = "vcode:"; private static final String KEY_PREFIX_MOBILE_VERIFY_CODE = "vcode:";
public static String VERIFY_CODE_KEY(String mobile) { private static final String KEY_PREFIX_EMAIL_ACTIVE_CODE = "email_active_code:";
return VERIFY_CODE_KEY_PREFIX + mobile;
/**
* 手机验证码
* @param mobile
* @return
*/
public static String MOBILE_VERIFY_CODE(String mobile) {
return KEY_PREFIX_MOBILE_VERIFY_CODE + mobile;
} }
public static String EMAIL_ACTIVE_CODE(String activeCode) {
return KEY_PREFIX_EMAIL_ACTIVE_CODE + activeCode;
}
} }
package cn.meteor.beyondclouds.modules.mail.dto;
import lombok.Data;
import java.io.Serializable;
/**
* @author meteor
*/
@Data
public class EmailDTO implements Serializable {
public EmailDTO() {
}
/**
*
* @param from
* @param to
* @param subject
* @param text
*/
public EmailDTO(String from, String[] to, String subject, String text) {
this.from = from;
this.to = to;
this.subject = subject;
this.text = text;
}
/**
*
* @param from
* @param to
* @param subject
* @param text
*/
public EmailDTO(String from, String to, String subject, String text) {
this.from = from;
this.to = new String[] {to};
this.subject = subject;
this.text = text;
}
/**
* 发送者
*/
private String from;
/**
* 接受者
*/
private String[] to;
/**
* 邮件主题
*/
private String subject;
/**
* 邮件内容
*/
private String text;
}
package cn.meteor.beyondclouds.modules.mail.service;
import cn.meteor.beyondclouds.modules.mail.dto.EmailDTO;
/**
* 邮件服务
* @author meteor
*/
public interface IMailService {
/**
* 发送简单邮件
* @param email
*/
void sendSimpleMail(EmailDTO email);
/**
* 发送html邮件
* @param email
*/
void sendHtmlMail(EmailDTO email);
}
package cn.meteor.beyondclouds.modules.mail.service.impl;
import cn.meteor.beyondclouds.modules.mail.dto.EmailDTO;
import cn.meteor.beyondclouds.modules.mail.service.IMailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import javax.mail.internet.MimeMessage;
/**
* @author meteor
*/
@Slf4j
@Service
public class MailServiceImpl implements IMailService {
private JavaMailSender mailSender;
@Autowired
public MailServiceImpl(JavaMailSender mailSender) {
this.mailSender = mailSender;
}
@Override
public void sendSimpleMail(EmailDTO email) {
try {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(email.getFrom());
message.setTo(email.getTo());
message.setSubject(email.getSubject());
message.setText(email.getText());
mailSender.send(message);
} catch (Exception e) {
log.error("发送邮件异常!",e.getMessage());
e.printStackTrace();
}
}
@Override
public void sendHtmlMail(EmailDTO email) {
MimeMessage message = null;
try {
message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(email.getFrom());
helper.setTo(email.getTo());
helper.setSubject(email.getSubject());
// 发送htmltext值需要给个true,不然不生效
helper.setText(email.getText(), true);
mailSender.send(message);
} catch (Exception e) {
log.error("发送邮件异常!", e.getMessage());
}
}
}
...@@ -9,7 +9,6 @@ import cn.meteor.beyondclouds.modules.sms.service.ISmsService; ...@@ -9,7 +9,6 @@ import cn.meteor.beyondclouds.modules.sms.service.ISmsService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
...@@ -35,7 +34,7 @@ public class SmsServiceImpl implements ISmsService { ...@@ -35,7 +34,7 @@ public class SmsServiceImpl implements ISmsService {
smsHelper.sendSms(smsHelper.getTemplateCodeMap().get("verifyCode"), Map.of("code", randomVerifyCode), mobile); smsHelper.sendSms(smsHelper.getTemplateCodeMap().get("verifyCode"), Map.of("code", randomVerifyCode), mobile);
//2.存储短信到redis //2.存储短信到redis
redisHelper.set(RedisKey.VERIFY_CODE_KEY(mobile), randomVerifyCode, 5 * 60); redisHelper.set(RedisKey.MOBILE_VERIFY_CODE(mobile), randomVerifyCode, 5 * 60);
} catch (Exception e) { } catch (Exception e) {
throw new SmsServiceException(SmsErrorCode.SEND_FAILURE); throw new SmsServiceException(SmsErrorCode.SEND_FAILURE);
} }
......
...@@ -35,10 +35,10 @@ public class AuthenticationApi { ...@@ -35,10 +35,10 @@ public class AuthenticationApi {
@Anonymous @Anonymous
@ApiOperation(value = "账号密码认证") @ApiOperation(value = "账号密码认证")
@PostMapping("/password") @PostMapping("/password")
public Response<AuthenticationResult> localAuth(@RequestBody @Valid @ApiParam("本地认证表单") LocalAuthFrom localAuthFrom) { public Response<AuthenticationResult> localAuth(@RequestBody @Valid LocalAuthFrom localAuthFrom) {
AuthenticationResult authenticationResult = null; AuthenticationResult authenticationResult = null;
try { try {
authenticationResult = authenticationService.localAuthentication(localAuthFrom.getMobile(), localAuthFrom.getPassword()); authenticationResult = authenticationService.localAuthentication(localAuthFrom.getAccount(), localAuthFrom.getPassword());
return Response.success(authenticationResult); return Response.success(authenticationResult);
} catch (AuthenticationServiceException e) { } catch (AuthenticationServiceException e) {
e.printStackTrace(); e.printStackTrace();
......
...@@ -10,8 +10,9 @@ import cn.meteor.beyondclouds.modules.user.entity.User; ...@@ -10,8 +10,9 @@ import cn.meteor.beyondclouds.modules.user.entity.User;
import cn.meteor.beyondclouds.modules.user.entity.UserBlacklist; import cn.meteor.beyondclouds.modules.user.entity.UserBlacklist;
import cn.meteor.beyondclouds.modules.user.entity.UserFollow; import cn.meteor.beyondclouds.modules.user.entity.UserFollow;
import cn.meteor.beyondclouds.modules.user.exception.UserServiceException; import cn.meteor.beyondclouds.modules.user.exception.UserServiceException;
import cn.meteor.beyondclouds.modules.user.form.EmailRegisterFrom;
import cn.meteor.beyondclouds.modules.user.form.UserBaseInfoFrom; import cn.meteor.beyondclouds.modules.user.form.UserBaseInfoFrom;
import cn.meteor.beyondclouds.modules.user.form.UserRegisterFrom; import cn.meteor.beyondclouds.modules.user.form.MobileRegisterFrom;
import cn.meteor.beyondclouds.modules.user.service.IUserBlacklistService; import cn.meteor.beyondclouds.modules.user.service.IUserBlacklistService;
import cn.meteor.beyondclouds.modules.user.service.IUserFollowService; import cn.meteor.beyondclouds.modules.user.service.IUserFollowService;
import cn.meteor.beyondclouds.modules.user.service.IUserService; import cn.meteor.beyondclouds.modules.user.service.IUserService;
...@@ -49,16 +50,48 @@ public class UserApi { ...@@ -49,16 +50,48 @@ public class UserApi {
} }
@Anonymous @Anonymous
@ApiOperation("用户注册") @ApiOperation("手机号注册")
@PostMapping("/user/register/mobile") @PostMapping("/user/register/mobile")
public Response register(@RequestBody @Valid UserRegisterFrom registerFrom, BindingResult result) { public Response mobileRegister(@RequestBody @Valid MobileRegisterFrom registerFrom, BindingResult result) {
if (result.hasErrors()) { if (result.hasErrors()) {
return Response.fieldError(result.getFieldError()); return Response.fieldError(result.getFieldError());
} }
try { try {
userService.register(registerFrom.getMobile(), registerFrom.getPassword(), registerFrom.getVerifyCode()); userService.registerByMobile(registerFrom.getMobile(), registerFrom.getPassword(), registerFrom.getVerifyCode());
return Response.success();
} catch (UserServiceException e) {
e.printStackTrace();
return Response.error(e);
}
}
@Anonymous
@ApiOperation("邮箱注册")
@PostMapping("/user/register/email")
public Response emailRegister(@RequestBody @Valid EmailRegisterFrom registerFrom, BindingResult result) {
if (result.hasErrors()) {
return Response.fieldError(result.getFieldError());
}
try {
userService.registerByEmail(registerFrom.getEmail(), registerFrom.getPassword());
return Response.success();
} catch (UserServiceException e) {
e.printStackTrace();
return Response.error(e);
}
}
@Anonymous
@ApiOperation("激活账号")
@PostMapping("/user/active/{activeCode}")
public Response emailRegister(@PathVariable("activeCode") String activeCode) {
try {
userService.activeAccount(activeCode);
return Response.success(); return Response.success();
} catch (UserServiceException e) { } catch (UserServiceException e) {
e.printStackTrace(); e.printStackTrace();
...@@ -87,7 +120,7 @@ public class UserApi { ...@@ -87,7 +120,7 @@ public class UserApi {
@Anonymous @Anonymous
@ApiOperation("修改密码") @ApiOperation("修改密码")
@PutMapping("/my/password") @PutMapping("/my/password")
public Response alterPassword(@RequestBody @Valid UserRegisterFrom registerFrom, BindingResult result){ public Response alterPassword(@RequestBody @Valid MobileRegisterFrom registerFrom, BindingResult result){
if (result.hasErrors()) { if (result.hasErrors()) {
return Response.fieldError(result.getFieldError()); return Response.fieldError(result.getFieldError());
......
package cn.meteor.beyondclouds.modules.user.entity; package cn.meteor.beyondclouds.modules.user.entity;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/** /**
* <p> * <p>
* 用户信息表 * 用户信息表
...@@ -44,6 +45,9 @@ public class User implements Serializable { ...@@ -44,6 +45,9 @@ public class User implements Serializable {
@ApiModelProperty(value = "手机号") @ApiModelProperty(value = "手机号")
private String mobile; private String mobile;
@ApiModelProperty(value = "邮箱")
private String email;
@ApiModelProperty(value = "微信号") @ApiModelProperty(value = "微信号")
private String wxNumber; private String wxNumber;
......
package cn.meteor.beyondclouds.modules.user.entity; package cn.meteor.beyondclouds.modules.user.entity;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/** /**
* <p> * <p>
* 用户本地认证表 * 用户本地认证表
...@@ -32,12 +33,29 @@ public class UserAuthLocal implements Serializable { ...@@ -32,12 +33,29 @@ public class UserAuthLocal implements Serializable {
@ApiModelProperty(value = "用户ID") @ApiModelProperty(value = "用户ID")
private String userId; private String userId;
@ApiModelProperty(value = "手机号") @ApiModelProperty(value = "账号")
private String mobile; private String account;
/**
* 账号类型
* 1-手机号
* 2-邮箱账号
*/
@ApiModelProperty(value = "账号类型")
private Integer accountType;
@ApiModelProperty(value = "密码") @ApiModelProperty(value = "密码")
private String password; private String password;
/**
* 状态:
* -1-被禁用
* 0-待激活
* 1-正常
*/
@ApiModelProperty(value = "状态")
private Integer status;
private Date createTime; private Date createTime;
private Date updateTime; private Date updateTime;
......
package cn.meteor.beyondclouds.modules.user.enums;
import lombok.Getter;
/**
* 账号类型
* @author meteor
*/
@Getter
public enum AccountType {
/**
* 手机号
*/
MOBILE(1, "手机号"),
/**
* 邮箱
*/
EMAIL(2,"邮箱账号")
;
AccountType(int type, String name) {
this.type = type;
this.name = name;
}
private int type;
private String name;
}
package cn.meteor.beyondclouds.modules.user.enums;
import lombok.Getter;
/**
* 账号类型
* @author meteor
*/
@Getter
public enum AuthStatus {
/**
* 认证方式被禁用
*/
DISABLED(-1, "禁用"),
/**
* 认证方式待激活
*/
WAIT_FOR_ACTIVE(0,"待激活"),
/**
* 正常
*/
NORMAL(1,"正常")
;
AuthStatus(int status, String name) {
this.status = status;
this.name = name;
}
private int status;
private String name;
}
...@@ -13,7 +13,9 @@ public enum AuthenticationErrorCode implements IErrorCode { ...@@ -13,7 +13,9 @@ public enum AuthenticationErrorCode implements IErrorCode {
*/ */
USER_NOT_FOUND(1001, "不存在该用户"), USER_NOT_FOUND(1001, "不存在该用户"),
PASSWORD_NOT_MATCHED(1002, "密码不匹配"), PASSWORD_NOT_MATCHED(1002, "密码不匹配"),
QQ_AUTH_ERROR(1004, "QQ认证失败"); QQ_AUTH_ERROR(1004, "QQ认证失败"),
USER_AUTH_DISABLED(1005, "该账号已被禁用"),
ACCOUNT_NOT_ACTIVE(1006, "请先激活该账号");
AuthenticationErrorCode(long code, String msg) { AuthenticationErrorCode(long code, String msg) {
this.code = code; this.code = code;
......
...@@ -12,16 +12,18 @@ public enum UserErrorCode implements IErrorCode { ...@@ -12,16 +12,18 @@ public enum UserErrorCode implements IErrorCode {
* 手机号已经被注册// * 手机号已经被注册//
*/ */
MOBILE_REGISTERED(1001, "该手机号已被注册"), MOBILE_REGISTERED(1001, "该手机号已被注册"),
REG_VERIFY_CODE_ERROR(1002, "验证码错误"), EMAIL_REGISTERED(1002, "该邮箱已被注册"),
CAN_NOT_FOLLOW_SELF(1003, "不能关注自己"), REG_VERIFY_CODE_ERROR(1003, "验证码错误"),
FOLLOWED_USER_NOT_EXISTS(1004, "被关注用户不存在"), CAN_NOT_FOLLOW_SELF(1004, "不能关注自己"),
FOLLOWER_USER_NOT_EXISTS(1005, "关注者不存在"), FOLLOWED_USER_NOT_EXISTS(1005, "被关注用户不存在"),
ALREADY_FOLLOWED(1006, "已关注过该用户"), FOLLOWER_USER_NOT_EXISTS(1006, "关注者不存在"),
NON_FOLLOWED(1007, "没有关注过该用户"), ALREADY_FOLLOWED(1007, "已关注过该用户"),
USER_ALREADY_BLACKED(1008,"用户已经被你拉进黑名单"), NON_FOLLOWED(1008, "没有关注过该用户"),
YOU_ALREADY_BLACKED(1009,"你已经被对方拉进黑名单"), USER_ALREADY_BLACKED(1009,"用户已经被你拉进黑名单"),
CAN_NOT_BLACKE_SELF(1010,"不能拉黑自己"), YOU_ALREADY_BLACKED(10010,"你已经被对方拉进黑名单"),
USER_NOT_BLACKED(1011,"用户没有被拉黑"); CAN_NOT_BLACK_SELF(10011,"不能拉黑自己"),
USER_NOT_BLACKED(10012,"用户没有被拉黑"),
INVALID_ACTIVE_CODE(10013, "非法的激活码");
UserErrorCode(long code, String msg) { UserErrorCode(long code, String msg) {
this.code = code; this.code = code;
......
package cn.meteor.beyondclouds.modules.user.form;
import lombok.Data;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* @author meteor
*/
@Data
public class EmailRegisterFrom {
@Email(message = "邮箱格式不准确")
@NotNull(message = "邮箱不能为空")
private String email;
@NotEmpty(message = "密码不能为空")
private String password;
}
...@@ -8,12 +8,12 @@ import lombok.Data; ...@@ -8,12 +8,12 @@ import lombok.Data;
* @author meteor * @author meteor
*/ */
@ApiModel("本地认证表单") @ApiModel("密码认证表单")
@Data @Data
public class LocalAuthFrom { public class LocalAuthFrom {
@ApiModelProperty("手机号") @ApiModelProperty("号")
private String mobile; private String account;
@ApiModelProperty("密码") @ApiModelProperty("密码")
private String password; private String password;
......
...@@ -11,7 +11,7 @@ import javax.validation.constraints.Pattern; ...@@ -11,7 +11,7 @@ import javax.validation.constraints.Pattern;
* @author meteor * @author meteor
*/ */
@Data @Data
public class UserRegisterFrom { public class MobileRegisterFrom {
@NotEmpty(message = "手机不能为空") @NotEmpty(message = "手机不能为空")
@NotNull(message = "手机号不能为空") @NotNull(message = "手机号不能为空")
......
...@@ -12,11 +12,11 @@ public interface IAuthenticationService { ...@@ -12,11 +12,11 @@ public interface IAuthenticationService {
/** /**
* 根据手机号和密码认证用户 * 根据手机号和密码认证用户
* @param mobile * @param account
* @param password * @param password
* @return * @return
*/ */
AuthenticationResult localAuthentication(String mobile, String password) throws AuthenticationServiceException; AuthenticationResult localAuthentication(String account, String password) throws AuthenticationServiceException;
/** /**
* QQ认证 * QQ认证
......
...@@ -10,6 +10,13 @@ public interface IUserAuthLocalService extends IService<UserAuthLocal> { ...@@ -10,6 +10,13 @@ public interface IUserAuthLocalService extends IService<UserAuthLocal> {
/** /**
* 根据账号查询本地认证信息
* @param account
* @return
*/
UserAuthLocal getByAccount(String account);
/**
* 根据手机号查询本地认证信息 * 根据手机号查询本地认证信息
* @param mobile * @param mobile
* @return * @return
......
...@@ -17,15 +17,15 @@ public interface IUserService extends IService<User> { ...@@ -17,15 +17,15 @@ public interface IUserService extends IService<User> {
* @param verifyCode * @param verifyCode
* @exception UserServiceException * @exception UserServiceException
*/ */
void register(String mobile, String password, String verifyCode) throws UserServiceException; void registerByMobile(String mobile, String password, String verifyCode) throws UserServiceException;
/** /**
* 根据手机号查找用户 * 邮箱注册
* @param mobile * @param email
* @return * @param password
* @throws UserServiceException
*/ */
User getByMobile(String mobile); void registerByEmail(String email, String password) throws UserServiceException;
/** /**
* 修改昵称 * 修改昵称
...@@ -56,4 +56,9 @@ public interface IUserService extends IService<User> { ...@@ -56,4 +56,9 @@ public interface IUserService extends IService<User> {
*/ */
void alterPassword(String mobile, String password, String verifyCode) throws UserServiceException; void alterPassword(String mobile, String password, String verifyCode) throws UserServiceException;
/**
* 激活账号
* @param activeCode
*/
void activeAccount(String activeCode) throws UserServiceException;
} }
...@@ -5,26 +5,24 @@ import cn.meteor.beyondclouds.common.exception.QQAuthenticationException; ...@@ -5,26 +5,24 @@ import cn.meteor.beyondclouds.common.exception.QQAuthenticationException;
import cn.meteor.beyondclouds.common.helper.IQQAuthenticationHelper; import cn.meteor.beyondclouds.common.helper.IQQAuthenticationHelper;
import cn.meteor.beyondclouds.common.helper.IRedisHelper; import cn.meteor.beyondclouds.common.helper.IRedisHelper;
import cn.meteor.beyondclouds.core.redis.RedisKey; import cn.meteor.beyondclouds.core.redis.RedisKey;
import cn.meteor.beyondclouds.modules.user.bean.AuthenticationResult;
import cn.meteor.beyondclouds.modules.user.entity.UserAuthApp; import cn.meteor.beyondclouds.modules.user.entity.UserAuthApp;
import cn.meteor.beyondclouds.modules.user.entity.UserAuthLocal; import cn.meteor.beyondclouds.modules.user.entity.UserAuthLocal;
import cn.meteor.beyondclouds.modules.user.enums.ThirdPartyAppType; import cn.meteor.beyondclouds.modules.user.enums.AuthStatus;
import cn.meteor.beyondclouds.modules.user.enums.AuthenticationErrorCode;
import cn.meteor.beyondclouds.modules.user.enums.UserErrorCode; import cn.meteor.beyondclouds.modules.user.enums.UserErrorCode;
import cn.meteor.beyondclouds.modules.user.exception.AuthenticationServiceException;
import cn.meteor.beyondclouds.modules.user.exception.UserServiceException; import cn.meteor.beyondclouds.modules.user.exception.UserServiceException;
import cn.meteor.beyondclouds.modules.user.service.IAuthenticationService;
import cn.meteor.beyondclouds.modules.user.service.IUserAuthAppService; import cn.meteor.beyondclouds.modules.user.service.IUserAuthAppService;
import cn.meteor.beyondclouds.modules.user.service.IUserAuthLocalService;
import cn.meteor.beyondclouds.modules.user.service.IUserService; import cn.meteor.beyondclouds.modules.user.service.IUserService;
import cn.meteor.beyondclouds.util.JsonUtils;
import cn.meteor.beyondclouds.util.JwtUtils; import cn.meteor.beyondclouds.util.JwtUtils;
import cn.meteor.beyondclouds.modules.user.bean.AuthenticationResult;
import cn.meteor.beyondclouds.modules.user.enums.AuthenticationErrorCode;
import cn.meteor.beyondclouds.modules.user.exception.AuthenticationServiceException;
import cn.meteor.beyondclouds.modules.user.service.IAuthenticationService;
import cn.meteor.beyondclouds.modules.user.service.IUserAuthLocalService;
import cn.meteor.beyondclouds.util.Md5Utils; import cn.meteor.beyondclouds.util.Md5Utils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
...@@ -59,14 +57,23 @@ public class AuthenticationServiceImpl implements IAuthenticationService { ...@@ -59,14 +57,23 @@ public class AuthenticationServiceImpl implements IAuthenticationService {
} }
@Override @Override
public AuthenticationResult localAuthentication(String mobile, String password) throws AuthenticationServiceException { public AuthenticationResult localAuthentication(String account, String password) throws AuthenticationServiceException {
//1. 查找用户是否存在 //1. 查找用户是否存在
UserAuthLocal userAuthLocal = userAuthLocalService.getByMobile(mobile); UserAuthLocal userAuthLocal = userAuthLocalService.getByAccount(account);
if (null == userAuthLocal) { if (null == userAuthLocal) {
throw new AuthenticationServiceException(AuthenticationErrorCode.USER_NOT_FOUND); throw new AuthenticationServiceException(AuthenticationErrorCode.USER_NOT_FOUND);
} }
//2. 判断密码是否正确 //2. 判断账号状态
if (userAuthLocal.getStatus() == AuthStatus.DISABLED.getStatus()) {
throw new AuthenticationServiceException(AuthenticationErrorCode.USER_AUTH_DISABLED);
}
if (userAuthLocal.getStatus() == AuthStatus.WAIT_FOR_ACTIVE.getStatus()) {
throw new AuthenticationServiceException(AuthenticationErrorCode.ACCOUNT_NOT_ACTIVE);
}
//3. 判断密码是否正确
String encodedPassword = Md5Utils.encode(password); String encodedPassword = Md5Utils.encode(password);
if (!encodedPassword.equals(userAuthLocal.getPassword())) { if (!encodedPassword.equals(userAuthLocal.getPassword())) {
throw new AuthenticationServiceException(AuthenticationErrorCode.PASSWORD_NOT_MATCHED); throw new AuthenticationServiceException(AuthenticationErrorCode.PASSWORD_NOT_MATCHED);
...@@ -108,19 +115,20 @@ public class AuthenticationServiceImpl implements IAuthenticationService { ...@@ -108,19 +115,20 @@ public class AuthenticationServiceImpl implements IAuthenticationService {
@Override @Override
public AuthenticationResult smsAuthentication(String mobile, String verifyCode) throws UserServiceException, AuthenticationServiceException { public AuthenticationResult smsAuthentication(String mobile, String verifyCode) throws UserServiceException, AuthenticationServiceException {
//1. 查找用户是否存在 //1.检查验证码是否正确
String realVerifyCode = redisHelper.get(RedisKey.MOBILE_VERIFY_CODE(mobile));
if (StringUtils.isEmpty(realVerifyCode) || !realVerifyCode.equals(verifyCode)) {
throw new UserServiceException(UserErrorCode.REG_VERIFY_CODE_ERROR);
}
//2. 查找认证信息是否存在
UserAuthLocal userAuthLocal = userAuthLocalService.getByMobile(mobile); UserAuthLocal userAuthLocal = userAuthLocalService.getByMobile(mobile);
if (null == userAuthLocal) { if (null == userAuthLocal) {
throw new AuthenticationServiceException(AuthenticationErrorCode.USER_NOT_FOUND); throw new AuthenticationServiceException(AuthenticationErrorCode.USER_NOT_FOUND);
} }
//2.检查验证码是否正确
String realVerifyCode = redisHelper.get(RedisKey.VERIFY_CODE_KEY(mobile));
if (StringUtils.isEmpty(realVerifyCode) || !realVerifyCode.equals(verifyCode)) {
throw new UserServiceException(UserErrorCode.REG_VERIFY_CODE_ERROR);
}
// 删除验证码 // 删除验证码
redisHelper.del(RedisKey.VERIFY_CODE_KEY(mobile)); redisHelper.del(RedisKey.MOBILE_VERIFY_CODE(mobile));
// 根据userId生成token并返回 // 根据userId生成token并返回
......
package cn.meteor.beyondclouds.modules.user.service.impl; package cn.meteor.beyondclouds.modules.user.service.impl;
import cn.meteor.beyondclouds.modules.user.entity.UserAuthLocal; import cn.meteor.beyondclouds.modules.user.entity.UserAuthLocal;
import cn.meteor.beyondclouds.modules.user.enums.AccountType;
import cn.meteor.beyondclouds.modules.user.mapper.IUserAuthLocalMapper; import cn.meteor.beyondclouds.modules.user.mapper.IUserAuthLocalMapper;
import cn.meteor.beyondclouds.modules.user.service.IUserAuthLocalService; import cn.meteor.beyondclouds.modules.user.service.IUserAuthLocalService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
...@@ -22,9 +23,17 @@ public class UserAuthLocalServiceImpl extends ServiceImpl<IUserAuthLocalMapper, ...@@ -22,9 +23,17 @@ public class UserAuthLocalServiceImpl extends ServiceImpl<IUserAuthLocalMapper,
} }
@Override @Override
public UserAuthLocal getByAccount(String account) {
QueryWrapper<UserAuthLocal> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("account", account);
return getOne(queryWrapper);
}
@Override
public UserAuthLocal getByMobile(String mobile) { public UserAuthLocal getByMobile(String mobile) {
QueryWrapper<UserAuthLocal> queryWrapper = new QueryWrapper<>(); QueryWrapper<UserAuthLocal> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("mobile", mobile); queryWrapper.eq("account", mobile);
queryWrapper.eq("account_type", AccountType.MOBILE.getType());
return getOne(queryWrapper); return getOne(queryWrapper);
} }
} }
...@@ -32,7 +32,7 @@ public class UserBlacklistServiceImpl extends ServiceImpl<UserBlacklistMapper, U ...@@ -32,7 +32,7 @@ public class UserBlacklistServiceImpl extends ServiceImpl<UserBlacklistMapper, U
// 自己不能拉黑自己 // 自己不能拉黑自己
if (userId.equals(blackedId)) { if (userId.equals(blackedId)) {
throw new UserServiceException(UserErrorCode.CAN_NOT_BLACKE_SELF); throw new UserServiceException(UserErrorCode.CAN_NOT_BLACK_SELF);
} }
//查询 是否用户已被拉黑 //查询 是否用户已被拉黑
QueryWrapper<UserBlacklist> myBlackListQueryWrapper = new QueryWrapper<>(); QueryWrapper<UserBlacklist> myBlackListQueryWrapper = new QueryWrapper<>();
......
...@@ -3,9 +3,13 @@ package cn.meteor.beyondclouds.modules.user.service.impl; ...@@ -3,9 +3,13 @@ package cn.meteor.beyondclouds.modules.user.service.impl;
import cn.meteor.beyondclouds.common.bean.QQAuthResult; import cn.meteor.beyondclouds.common.bean.QQAuthResult;
import cn.meteor.beyondclouds.common.helper.IRedisHelper; import cn.meteor.beyondclouds.common.helper.IRedisHelper;
import cn.meteor.beyondclouds.core.redis.RedisKey; import cn.meteor.beyondclouds.core.redis.RedisKey;
import cn.meteor.beyondclouds.modules.mail.dto.EmailDTO;
import cn.meteor.beyondclouds.modules.mail.service.IMailService;
import cn.meteor.beyondclouds.modules.user.entity.User; import cn.meteor.beyondclouds.modules.user.entity.User;
import cn.meteor.beyondclouds.modules.user.entity.UserAuthApp; import cn.meteor.beyondclouds.modules.user.entity.UserAuthApp;
import cn.meteor.beyondclouds.modules.user.entity.UserAuthLocal; import cn.meteor.beyondclouds.modules.user.entity.UserAuthLocal;
import cn.meteor.beyondclouds.modules.user.enums.AccountType;
import cn.meteor.beyondclouds.modules.user.enums.AuthStatus;
import cn.meteor.beyondclouds.modules.user.enums.ThirdPartyAppType; import cn.meteor.beyondclouds.modules.user.enums.ThirdPartyAppType;
import cn.meteor.beyondclouds.modules.user.enums.UserErrorCode; import cn.meteor.beyondclouds.modules.user.enums.UserErrorCode;
import cn.meteor.beyondclouds.modules.user.exception.UserServiceException; import cn.meteor.beyondclouds.modules.user.exception.UserServiceException;
...@@ -13,13 +17,16 @@ import cn.meteor.beyondclouds.modules.user.mapper.IUserMapper; ...@@ -13,13 +17,16 @@ import cn.meteor.beyondclouds.modules.user.mapper.IUserMapper;
import cn.meteor.beyondclouds.modules.user.service.IUserAuthAppService; import cn.meteor.beyondclouds.modules.user.service.IUserAuthAppService;
import cn.meteor.beyondclouds.modules.user.service.IUserAuthLocalService; import cn.meteor.beyondclouds.modules.user.service.IUserAuthLocalService;
import cn.meteor.beyondclouds.modules.user.service.IUserService; import cn.meteor.beyondclouds.modules.user.service.IUserService;
import cn.meteor.beyondclouds.modules.user.util.ActivceCodeEmailUtils;
import cn.meteor.beyondclouds.util.Md5Utils; import cn.meteor.beyondclouds.util.Md5Utils;
import cn.meteor.beyondclouds.util.UUIDUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
...@@ -32,28 +39,30 @@ public class UserServiceImpl extends ServiceImpl<IUserMapper, User> implements I ...@@ -32,28 +39,30 @@ public class UserServiceImpl extends ServiceImpl<IUserMapper, User> implements I
private IUserAuthLocalService userAuthLocalService; private IUserAuthLocalService userAuthLocalService;
private IRedisHelper redisHelper; private IRedisHelper redisHelper;
private IUserAuthAppService userAuthAppService; private IUserAuthAppService userAuthAppService;
private IMailService mailService;
@Autowired @Autowired
public UserServiceImpl(IUserAuthLocalService userAuthLocalService, IRedisHelper redisHelper, IUserAuthAppService userAuthAppService) { public UserServiceImpl(IUserAuthLocalService userAuthLocalService, IRedisHelper redisHelper, IUserAuthAppService userAuthAppService, IMailService mailService) {
this.userAuthLocalService = userAuthLocalService; this.userAuthLocalService = userAuthLocalService;
this.redisHelper = redisHelper; this.redisHelper = redisHelper;
this.userAuthAppService = userAuthAppService; this.userAuthAppService = userAuthAppService;
this.mailService = mailService;
} }
@Override @Override
public void register(String mobile, String password, String verifyCode) throws UserServiceException { public void registerByMobile(String mobile, String password, String verifyCode) throws UserServiceException {
//1.检查验证码是否正确 //1.检查验证码是否正确
String realVerifyCode = redisHelper.get(RedisKey.VERIFY_CODE_KEY(mobile)); String realVerifyCode = redisHelper.get(RedisKey.MOBILE_VERIFY_CODE(mobile));
if (StringUtils.isEmpty(realVerifyCode) || !realVerifyCode.equals(verifyCode)) { if (StringUtils.isEmpty(realVerifyCode) || !realVerifyCode.equals(verifyCode)) {
throw new UserServiceException(UserErrorCode.REG_VERIFY_CODE_ERROR); throw new UserServiceException(UserErrorCode.REG_VERIFY_CODE_ERROR);
} }
// 删除验证码 // 删除验证码
redisHelper.del(RedisKey.VERIFY_CODE_KEY(mobile)); redisHelper.del(RedisKey.MOBILE_VERIFY_CODE(mobile));
//2. 检测该手机号是否被注册 //2. 检测该手机号是否被注册
QueryWrapper<UserAuthLocal> queryWrapper = new QueryWrapper<>(); QueryWrapper<UserAuthLocal> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("mobile", mobile); queryWrapper.eq("account", mobile);
UserAuthLocal userAuthLocal = userAuthLocalService.getOne(queryWrapper); UserAuthLocal userAuthLocal = userAuthLocalService.getOne(queryWrapper);
if (null != userAuthLocal) { if (null != userAuthLocal) {
throw new UserServiceException(UserErrorCode.MOBILE_REGISTERED); throw new UserServiceException(UserErrorCode.MOBILE_REGISTERED);
...@@ -70,22 +79,68 @@ public class UserServiceImpl extends ServiceImpl<IUserMapper, User> implements I ...@@ -70,22 +79,68 @@ public class UserServiceImpl extends ServiceImpl<IUserMapper, User> implements I
//4. 创建认证信息 //4. 创建认证信息
userAuthLocal = new UserAuthLocal(); userAuthLocal = new UserAuthLocal();
userAuthLocal.setUserId(user.getUserId()); userAuthLocal.setUserId(user.getUserId());
userAuthLocal.setMobile(mobile); userAuthLocal.setAccount(mobile);
// 将认证状态设置为正常
userAuthLocal.setStatus(AuthStatus.NORMAL.getStatus());
// 将账号类型设置为手机号
userAuthLocal.setAccountType(AccountType.MOBILE.getType());
userAuthLocal.setPassword(Md5Utils.encode(password)); userAuthLocal.setPassword(Md5Utils.encode(password));
userAuthLocalService.save(userAuthLocal); userAuthLocalService.save(userAuthLocal);
} }
/** @Transactional(rollbackFor = Exception.class)
* 根据手机号查找用户
* @param mobile
* @return
*/
@Override @Override
public User getByMobile(String mobile) { public void registerByEmail(String email, String password) throws UserServiceException {
QueryWrapper<User> queryWrapper = new QueryWrapper<>(); //1. 检测该邮箱是否被注册
queryWrapper.eq("mobile", mobile); QueryWrapper<UserAuthLocal> queryWrapper = new QueryWrapper<>();
return getOne(queryWrapper); queryWrapper.eq("account", email);
UserAuthLocal userAuthLocal = userAuthLocalService.getOne(queryWrapper);
if (null != userAuthLocal) {
throw new UserServiceException(UserErrorCode.EMAIL_REGISTERED);
}
//3. 创建用户
User user = new User();
user.setNickName("昵称");
user.setSignature("默认签名");
user.setUserAvatar("https://beyondclouds.oss-cn-beijing.aliyuncs.com/avatar/d389c748-f087-4d8e-a138-6756af8790b1.jpeg");
user.setEmail(email);
save(user);
//4. 创建并保存认证信息
userAuthLocal = new UserAuthLocal();
userAuthLocal.setUserId(user.getUserId());
userAuthLocal.setAccount(email);
// 将认证状态设置为待激活
userAuthLocal.setStatus(AuthStatus.WAIT_FOR_ACTIVE.getStatus());
// 将账号类型设置为邮箱账号
userAuthLocal.setAccountType(AccountType.EMAIL.getType());
userAuthLocal.setPassword(Md5Utils.encode(password));
userAuthLocalService.save(userAuthLocal);
// 5.生成激活码并存入redis,有效时间为24小时
generateAndSenActiveMail(email);
}
private void generateAndSenActiveMail(String email) {
// 生成激活码并存入redis
String activeCode = UUIDUtils.randomUUID();
redisHelper.set(RedisKey.EMAIL_ACTIVE_CODE(activeCode), email, 24 * 60 * 60);
// 激活邮件
String activeUrl = "http://opensource.yundingshuyuan.com/user/active/" + activeCode;
EmailDTO emailDTO = new EmailDTO("13546386889@163.com",
email, "云里云外激活邮件",
ActivceCodeEmailUtils.generateMail(activeUrl));
mailService.sendHtmlMail(emailDTO);
} }
@Override @Override
...@@ -125,17 +180,45 @@ public class UserServiceImpl extends ServiceImpl<IUserMapper, User> implements I ...@@ -125,17 +180,45 @@ public class UserServiceImpl extends ServiceImpl<IUserMapper, User> implements I
@Override @Override
public void alterPassword(String mobile, String password, String verifyCode) throws UserServiceException { public void alterPassword(String mobile, String password, String verifyCode) throws UserServiceException {
//1.检查验证码是否正确 //1.检查验证码是否正确
String realVerifyCode = redisHelper.get(RedisKey.VERIFY_CODE_KEY(mobile)); String realVerifyCode = redisHelper.get(RedisKey.MOBILE_VERIFY_CODE(mobile));
if (StringUtils.isEmpty(realVerifyCode) || !realVerifyCode.equals(verifyCode)) { if (StringUtils.isEmpty(realVerifyCode) || !realVerifyCode.equals(verifyCode)) {
throw new UserServiceException(UserErrorCode.REG_VERIFY_CODE_ERROR); throw new UserServiceException(UserErrorCode.REG_VERIFY_CODE_ERROR);
} }
// 删除验证码 // 删除验证码
redisHelper.del(RedisKey.VERIFY_CODE_KEY(mobile)); redisHelper.del(RedisKey.MOBILE_VERIFY_CODE(mobile));
UpdateWrapper updateWrapper = new UpdateWrapper(); UpdateWrapper updateWrapper = new UpdateWrapper();
updateWrapper.set("password", Md5Utils.encode(password)); updateWrapper.set("password", Md5Utils.encode(password));
updateWrapper.eq("mobile", mobile); updateWrapper.eq("mobile", mobile);
userAuthLocalService.update(updateWrapper); userAuthLocalService.update(updateWrapper);
} }
@Override
public void activeAccount(String activeCode) throws UserServiceException {
Assert.hasText(activeCode, "activeCode must not be empty");
// 1.校验激活码是否正确
String email = redisHelper.get(RedisKey.EMAIL_ACTIVE_CODE(activeCode));
if (null == email) {
throw new UserServiceException(UserErrorCode.INVALID_ACTIVE_CODE);
}
QueryWrapper<UserAuthLocal> userAuthLocalQueryWrapper = new QueryWrapper<>();
userAuthLocalQueryWrapper.eq("account", email);
userAuthLocalQueryWrapper.eq("account_type", AccountType.EMAIL.getType());
userAuthLocalQueryWrapper.eq("status", AuthStatus.WAIT_FOR_ACTIVE.getStatus());
UserAuthLocal userAuthLocal = userAuthLocalService.getOne(userAuthLocalQueryWrapper);
if (null == userAuthLocal) {
throw new UserServiceException(UserErrorCode.INVALID_ACTIVE_CODE);
}
// 2.激活账号
userAuthLocal.setStatus(AuthStatus.NORMAL.getStatus());
userAuthLocalService.updateById(userAuthLocal);
// 3.删除激活码
redisHelper.del(RedisKey.EMAIL_ACTIVE_CODE(activeCode));
}
} }
package cn.meteor.beyondclouds.modules.user.util;
/**
* @author meteor
*/
public class ActivceCodeEmailUtils {
/**
* 生成激活邮件
* @param activeUrl
* @return
*/
public static String generateMail(String activeUrl) {
StringBuilder builder = new StringBuilder();
builder.append("<html>");
builder.append("<head>");
builder.append("<title>");
builder.append("云里云外开源社区激活邮件");
builder.append("</title>");
builder.append("<meta charset=\"UTF-8\">");
builder.append("</head>");
builder.append("<body>");
builder.append("欢迎注册云里云外开源社区,请点击以下链接激活<br>");
builder.append("<a href=\"");
builder.append(activeUrl);
builder.append("\">");
builder.append(activeUrl);
builder.append("</a>");
builder.append("</body>");
builder.append("</html>");
return builder.toString();
}
public static void main(String[] args) {
System.out.println(generateMail("http://a.com/aaa"));
}
}
...@@ -4,6 +4,22 @@ spring: ...@@ -4,6 +4,22 @@ spring:
url: jdbc:mysql://127.0.0.1:3306/beyond_clouds?useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true url: jdbc:mysql://127.0.0.1:3306/beyond_clouds?useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true
username: beyond username: beyond
password: Beyond2020# password: Beyond2020#
mail:
host: smtp.163.com
username: 13546386889@163.com
password: 100centa30822
port: 465
default-encoding: UTF-8
properties:
mail:
smtp:
auth: true
ssl:
enable: true
imap:
ssl:
socketFactory:
fallback: false
swagger: swagger:
enable: true enable: true
......
...@@ -4,7 +4,22 @@ spring: ...@@ -4,7 +4,22 @@ spring:
url: jdbc:mysql://127.0.0.1:3306/beyond_clouds?useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true url: jdbc:mysql://127.0.0.1:3306/beyond_clouds?useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true
username: beyond username: beyond
password: Beyond2020# password: Beyond2020#
mail:
host: smtp.163.com
username: 13546386889@163.com
password: 100centa30822
port: 465
default-encoding: UTF-8
properties:
mail:
smtp:
auth: true
ssl:
enable: true
imap:
ssl:
socketFactory:
fallback: false
swagger: swagger:
enable: true enable: true
......
...@@ -4,6 +4,23 @@ spring: ...@@ -4,6 +4,23 @@ spring:
url: jdbc:mysql://127.0.0.1:3306/beyond_clouds?useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true url: jdbc:mysql://127.0.0.1:3306/beyond_clouds?useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true
username: root username: root
password: 100Centa30821%mysql password: 100Centa30821%mysql
mail:
host: smtp.163.com
username: 13546386889@163.com
password: 100centa30822
port: 465
default-encoding: UTF-8
properties:
mail:
smtp:
auth: true
ssl:
enable: true
imap:
ssl:
socketFactory:
fallback: false
swagger: swagger:
enable: true enable: true
......
package cn.meteor.beyondclouds.modules.mail.service;
import cn.meteor.beyondclouds.modules.mail.dto.EmailDTO;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import static org.junit.Assert.*;
@SpringBootTest
@RunWith(SpringRunner.class)
public class IMailServiceTest {
@Autowired
private IMailService mailService;
@Test
public void sendSimpleMail() {
EmailDTO email = new EmailDTO();
email.setFrom("13546386889@163.com");
email.setSubject("测试");
email.setText("hello");
email.setTo(new String[]{"1379681506@qq.com"});
mailService.sendSimpleMail(email);
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment