Commit 46cc0362 by Future

加解密工具类、用户登录注册更换手机号等

parent 43759dff
......@@ -201,6 +201,10 @@ spring-boot-plus:
- /Wecloud-IM-Websocket-Docs.html
# 服务端rest-API
- /server/**
# 用户注册登录
- /user/register, /user/login, /user/resetPassword, /user/checkPhone
# 发送短信验证码
- /verify/**
# 多行字符串权限配置
filter-chain-definitions: |
......
......@@ -24,14 +24,6 @@ import java.util.List;
public interface ImClientMapper extends BaseMapper<ImClient> {
/**
* 根据ID获取查询对象
*
* @param id
* @return
*/
ImClient getImClientById(Serializable id);
/**
* 获取分页对象
*
* @param page
......
package com.wecloud.im.user.controller;
import com.wecloud.im.enums.VerifySceneEnum;
import com.wecloud.im.user.constant.RedisKeyPrefixConstant;
import com.wecloud.im.user.param.ChangePhoneParam;
import com.wecloud.im.user.param.CheckPhoneParam;
import com.wecloud.im.user.param.LoginSuccessDto;
import com.wecloud.im.user.param.ResetPasswordParam;
import com.wecloud.im.user.param.UserLoginParam;
import com.wecloud.im.user.param.UserRegisterParam;
......@@ -34,26 +34,33 @@ public class UserController extends BaseController {
@Autowired
private UserService userService;
@PostMapping("/checkPhone")
@ApiOperation(value = "校验手机号码是否可使用 true-可使用 false-不可使用")
public ApiResult<Boolean> checkPhone(@RequestBody @Validated CheckPhoneParam param) {
if (param == null) {
return ApiResult.fail(ApiCode.PARAMETER_EXCEPTION, null);
}
return ApiResult.ok(userService.checkPhone(param));
}
@PostMapping("/register")
@ApiOperation(value = "用户注册接口")
public ApiResult<Boolean> register(@RequestBody @Validated UserRegisterParam param) {
public ApiResult<LoginSuccessDto> register(@RequestBody @Validated UserRegisterParam param) {
if (param == null) {
return ApiResult.fail(ApiCode.PARAMETER_EXCEPTION, null);
}
String key = new StringBuilder(RedisKeyPrefixConstant.VERIFY_CODE_PREFIX).append(VerifySceneEnum.REGISTER.getCode()).append(param.getPhone()).toString();
userService.verifySMSVerifyCode(param.getVerifyCode(), key);
userService.registerUser(param);
return ApiResult.ok();
String userId = userService.registerUser(param);
return ApiResult.ok(new LoginSuccessDto(userId));
}
@PostMapping("/login")
@ApiOperation(value = "用户登录接口")
public ApiResult<Boolean> login(@RequestBody @Validated UserLoginParam param) {
public ApiResult<LoginSuccessDto> login(@RequestBody @Validated UserLoginParam param) {
if (param == null) {
return ApiResult.fail(ApiCode.PARAMETER_EXCEPTION, null);
}
userService.loginUser(param);
return ApiResult.ok();
String userId = userService.loginUser(param);
return ApiResult.ok(new LoginSuccessDto(userId));
}
@PostMapping("/resetPassword")
......@@ -62,8 +69,6 @@ public class UserController extends BaseController {
if (param == null) {
return ApiResult.fail(ApiCode.PARAMETER_EXCEPTION, null);
}
String key = new StringBuilder(RedisKeyPrefixConstant.VERIFY_CODE_PREFIX).append(VerifySceneEnum.RESET_PWD.getCode()).append(param.getPhone()).toString();
userService.verifySMSVerifyCode(param.getVerifyCode(), key);
userService.resetPassword(param);
return ApiResult.ok();
}
......@@ -74,8 +79,6 @@ public class UserController extends BaseController {
if (param == null) {
return ApiResult.fail(ApiCode.PARAMETER_EXCEPTION, null);
}
String key = new StringBuilder(RedisKeyPrefixConstant.VERIFY_CODE_PREFIX).append(VerifySceneEnum.CHANGE_PHONE.getCode()).append(param.getPhone()).toString();
userService.verifySMSVerifyCode(param.getVerifyCode(), key);
userService.changePhone(param);
return ApiResult.ok();
}
......
package com.wecloud.im.user.controller;
import com.wecloud.im.enums.FriendStateEnum;
import com.wecloud.im.enums.VerifySceneEnum;
import com.wecloud.im.user.constant.RedisKeyPrefixConstant;
import com.wecloud.im.user.param.SendVerifyCodeParam;
import com.wecloud.im.ws.utils.RedisUtils;
import io.geekidea.springbootplus.framework.common.api.ApiCode;
import io.geekidea.springbootplus.framework.common.api.ApiResult;
import io.geekidea.springbootplus.framework.common.controller.BaseController;
import io.geekidea.springbootplus.framework.common.enums.BaseEnum;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
......@@ -35,17 +38,20 @@ public class VerifyCodeController extends BaseController {
/**
* 发送验证码接口
*/
@PostMapping("/sendVerificationCode")
@PostMapping("/sendVerifyCode")
@ApiOperation(value = "发送验证码接口")
public ApiResult<Boolean> generateVerificationCode(@RequestBody @Validated SendVerifyCodeParam param) {
public ApiResult<Boolean> sendVerifyCode(@RequestBody @Validated SendVerifyCodeParam param) {
if (param == null) {
return ApiResult.fail(ApiCode.PARAMETER_EXCEPTION, null);
}
// String verificationCode = this.generateVerifyCode();
String verificationCode = "666666";
if (BaseEnum.valueOf(VerifySceneEnum.class, param.getVerifyScene()) == null) {
return ApiResult.fail(ApiCode.PARAMETER_EXCEPTION, null);
}
// String verifyCode = this.generateVerifyCode();
String verifyCode = "666666";
String key = new StringBuilder(RedisKeyPrefixConstant.VERIFY_CODE_PREFIX).append(param.getVerifyScene()).append(param.getPhone()).toString();
redisUtils.addKey(key, verificationCode, Duration.ofSeconds(3 * 60));
// todo 接入短信验证码
redisUtils.addKey(key, verifyCode, Duration.ofSeconds(3 * 60));
// todo 接入短信推送
return ApiResult.ok();
}
......@@ -54,8 +60,7 @@ public class VerifyCodeController extends BaseController {
* @return
*/
private String generateVerifyCode() {
Integer verifyCode;
verifyCode = (int) ((Math.random() * 9 + 1) * 100000);
Integer verifyCode = (int) ((Math.random() * 9 + 1) * 100000);
return verifyCode.toString();
}
......
......@@ -2,6 +2,7 @@ package com.wecloud.im.user.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.geekidea.springbootplus.framework.common.entity.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
......@@ -21,6 +22,7 @@ import java.util.Date;
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "用户信息")
@TableName("im_user")
public class User extends BaseEntity {
private static final long serialVersionUID = -8075685205533406087L;
......@@ -49,7 +51,7 @@ public class User extends BaseEntity {
private String headPortrait;
@ApiModelProperty("昵称")
private String nickName;
private String nickname;
@ApiModelProperty("创建时间")
private Date createTime;
......
package com.wecloud.im.user.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
......@@ -16,15 +17,24 @@ public class ChangePhoneParam implements Serializable {
private static final long serialVersionUID = -4477687567118083363L;
/**
* userId
*/
@NotNull(message = "userId不可为空")
@ApiModelProperty("userId")
private String userId;
/**
* 电话号码
*/
@NotNull(message = "电话号码不可为空")
@ApiModelProperty("电话号码")
private String phone;
/**
* 验证码
*/
@NotNull(message = "验证码不可为空")
@ApiModelProperty("验证码")
private String verifyCode;
}
package com.wecloud.im.user.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/2/22 11:32
* @Description 校验手机号码有效入参
*/
@Data
public class CheckPhoneParam implements Serializable {
private static final long serialVersionUID = 5693166829929874726L;
/**
* 电话号码
*/
@NotNull(message = "电话号码不可为空")
@ApiModelProperty("电话号码")
private String phone;
}
package com.wecloud.im.user.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* @Author wenzhida
* @Date 2022/2/22 9:15
* @Description 用户登录成功dto
*/
@Data
@AllArgsConstructor
public class LoginSuccessDto implements Serializable {
private static final long serialVersionUID = 7813920366165375711L;
/**
* userId
*/
@ApiModelProperty("userId")
private String userId;
}
package com.wecloud.im.user.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
......@@ -19,18 +20,21 @@ public class ResetPasswordParam implements Serializable {
* 电话号码
*/
@NotNull(message = "电话号码不可为空")
@ApiModelProperty("电话号码")
private String phone;
/**
* 验证码
*/
@NotNull(message = "验证码不可为空")
@ApiModelProperty("验证码")
private String verifyCode;
/**
* 密码
*/
@NotNull(message = "密码不可为空")
@ApiModelProperty("密码")
private String password;
}
package com.wecloud.im.user.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
......@@ -19,6 +20,7 @@ public class SendVerifyCodeParam implements Serializable {
* 电话号码
*/
@NotNull(message = "电话号码不可为空")
@ApiModelProperty("电话号码")
private String phone;
/**
......@@ -26,6 +28,7 @@ public class SendVerifyCodeParam implements Serializable {
* @see com.wecloud.im.enums.VerifySceneEnum
*/
@NotNull(message = "验证场景不可为空")
@ApiModelProperty("验证场景 1-用户注册 2-重置密码验证 3-更换手机号绑定")
private Integer verifyScene;
}
package com.wecloud.im.user.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
......@@ -19,12 +20,14 @@ public class UserLoginParam implements Serializable {
* 电话号码
*/
@NotNull(message = "电话号码不可为空")
@ApiModelProperty("电话号码")
private String phone;
/**
* 密码
*/
@NotNull(message = "密码不可为空")
@ApiModelProperty("密码")
private String password;
}
package com.wecloud.im.user.param;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
......@@ -19,18 +20,21 @@ public class UserRegisterParam implements Serializable {
* 电话号码
*/
@NotNull(message = "电话号码不可为空")
@ApiModelProperty("电话号码")
private String phone;
/**
* 验证码
*/
@NotNull(message = "验证码不可为空")
@ApiModelProperty("验证码")
private String verifyCode;
/**
* 密码
*/
@NotNull(message = "密码不可为空")
@ApiModelProperty("密码")
private String password;
}
......@@ -3,9 +3,12 @@ package com.wecloud.im.user.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.protobuf.ServiceException;
import com.wecloud.im.entity.ImClient;
import com.wecloud.im.enums.VerifySceneEnum;
import com.wecloud.im.user.constant.RedisKeyPrefixConstant;
import com.wecloud.im.user.entity.User;
import com.wecloud.im.user.mapper.UserMapper;
import com.wecloud.im.user.param.ChangePhoneParam;
import com.wecloud.im.user.param.CheckPhoneParam;
import com.wecloud.im.user.param.ResetPasswordParam;
import com.wecloud.im.user.param.UserLoginParam;
import com.wecloud.im.user.param.UserRegisterParam;
......@@ -32,10 +35,25 @@ public class UserService extends BaseServiceImpl<UserMapper, User> {
private RedisUtils redisUtils;
/**
* 校验手机号码是否可使用
* @param param
*/
public Boolean checkPhone(CheckPhoneParam param) {
User userExist = this.getOne(new QueryWrapper<User>().lambda()
.eq(User::getPhone, param.getPhone()));
if (userExist != null) {
return Boolean.FALSE;
}
return Boolean.TRUE;
}
/**
* 注册用户
* @param param
*/
public void registerUser(UserRegisterParam param) {
public String registerUser(UserRegisterParam param) {
String key = new StringBuilder(RedisKeyPrefixConstant.VERIFY_CODE_PREFIX).append(VerifySceneEnum.REGISTER.getCode()).append(param.getPhone()).toString();
this.verifySMSVerifyCode(param.getVerifyCode(), key);
User userExist = this.getOne(new QueryWrapper<User>().lambda()
.eq(User::getPhone, param.getPhone()));
if (userExist != null) {
......@@ -46,19 +64,22 @@ public class UserService extends BaseServiceImpl<UserMapper, User> {
user.setPhone(param.getPhone());
user.setPassword(AesUtil.encrypt(param.getPassword()));
user.setCreateTime(new Date());
user.setUpdateTime(new Date());
this.save(user);
return String.valueOf(user.getId());
}
/**
* 用户登录
* @param param
*/
public void loginUser(UserLoginParam param) {
public String loginUser(UserLoginParam param) {
User user = this.getOne(new QueryWrapper<User>().lambda()
.eq(User::getPhone, param.getPhone()));
if (!param.getPassword().equals(AesUtil.decrypt(user.getPassword()))) {
throw new BusinessException("账户或密码错误");
}
return String.valueOf(user.getId());
}
/**
......@@ -66,6 +87,8 @@ public class UserService extends BaseServiceImpl<UserMapper, User> {
* @param param
*/
public void resetPassword(ResetPasswordParam param) {
String key = new StringBuilder(RedisKeyPrefixConstant.VERIFY_CODE_PREFIX).append(VerifySceneEnum.RESET_PWD.getCode()).append(param.getPhone()).toString();
this.verifySMSVerifyCode(param.getVerifyCode(), key);
User user = this.getOne(new QueryWrapper<User>().lambda()
.eq(User::getPhone, param.getPhone()));
if (user == null) {
......@@ -80,11 +103,22 @@ public class UserService extends BaseServiceImpl<UserMapper, User> {
* @param param
*/
public void changePhone(ChangePhoneParam param) {
String key = new StringBuilder(RedisKeyPrefixConstant.VERIFY_CODE_PREFIX).append(VerifySceneEnum.CHANGE_PHONE.getCode()).append(param.getPhone()).toString();
this.verifySMSVerifyCode(param.getVerifyCode(), key);
User user = this.getOne(new QueryWrapper<User>().lambda()
.eq(User::getPhone, param.getPhone()));
.eq(User::getId, param.getUserId()));
if (user == null) {
throw new BusinessException("查无此用户");
}
if (param.getPhone().equals(user.getPhone())) {
throw new BusinessException("更换后的手机号码与当前手机号码一致,无需更换");
}
User userExist = this.getOne(new QueryWrapper<User>().lambda()
.ne(User::getId, param.getUserId())
.eq(User::getPhone, param.getPhone()));
if (userExist != null) {
throw new BusinessException("新手机号码已被注册");
}
user.setPhone(param.getPhone());
this.updateById(user);
}
......
package com.wecloud.utils;
import io.geekidea.springbootplus.framework.common.exception.BusinessException;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
......@@ -13,70 +14,66 @@ import javax.crypto.spec.SecretKeySpec;
*/
public class AesUtil {
public static final String ALGORITHM = "AES";
private static final String S_KEY = "weeKeejjLL123.VB";
/**
* AES/CBC/NOPaddin
* AES 默认模式
* 使用CBC模式, 在初始化Cipher对象时, 需要增加参数, 初始化向量IV : IvParameterSpec iv = new
* IvParameterSpec(key.getBytes());
* NOPadding: 使用NOPadding模式时, 原文长度必须是8byte的整数倍
*/
public static final String TRANSFORMATION = "AES/CBC/NOPadding";
public static final String key = "1234567812345678";
/***
* 加密
* @param original 需要加密的参数(注意必须是16位)
* @param sSrc
* @return
* @throws Exception
*/
public static String encrypt(String original) {
public static String encrypt(String sSrc) {
try {
// 获取Cipher
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
// 生成密钥
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), ALGORITHM);
// 指定模式(加密)和密钥
// 创建初始化向量
IvParameterSpec iv = new IvParameterSpec(key.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
// cipher.init(Cipher.ENCRYPT_MODE, keySpec);
// 加密
byte[] bytes = cipher.doFinal(original.getBytes());
return Base64Util.encryptBASE64(bytes);
byte[] raw = S_KEY.getBytes("utf-8");
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
// "算法/模式/补码方式"
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(sSrc.getBytes("utf-8"));
// 此处使用BASE64做转码功能,同时能起到2次加密的作用。
return new BASE64Encoder().encode(encrypted);
} catch (Exception e) {
throw new BusinessException("加密出现错误");
throw new BusinessException("系统异常,稍后重试");
}
}
/**
* 解密
*
* @param encrypted 需要解密的参数
* @param sSrc
* @return
* @throws Exception
*/
public static String decrypt(String encrypted) {
public static String decrypt(String sSrc) {
try {
// 获取Cipher
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
// 生成密钥
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), ALGORITHM);
// 指定模式(解密)和密钥
// 创建初始化向量
IvParameterSpec iv = new IvParameterSpec(key.getBytes());
cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
// cipher.init(Cipher.DECRYPT_MODE, keySpec);
// 解密
byte[] bytes = cipher.doFinal(Base64Util.decryBASE64(encrypted));
return new String(bytes);
byte[] raw = S_KEY.getBytes("utf-8");
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] encrypted1 = new BASE64Decoder().decodeBuffer(sSrc);//先用base64解密
try {
byte[] original = cipher.doFinal(encrypted1);
String originalString = new String(original,"utf-8");
return originalString;
} catch (Exception e) {
throw new BusinessException("解密出现错误");
System.out.println(e.toString());
return null;
}
} catch (Exception ex) {
System.out.println(ex.toString());
return null;
}
}
public static void main(String[] args) throws Exception {
// 需要加密的字串
String cSrc = "123";
System.out.println(cSrc);
// 加密
String enString = AesUtil.encrypt(cSrc);
System.out.println("加密后的字串是:" + enString);
// 解密
String DeString = AesUtil.decrypt(enString);
System.out.println("解密后的字串是:" + DeString);
}
}
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