diff --git a/src/main/java/com/qzx/xdupartner/entity/vo/ResultCode.java b/src/main/java/com/qzx/xdupartner/entity/vo/ResultCode.java index 81cd1e8..383879e 100644 --- a/src/main/java/com/qzx/xdupartner/entity/vo/ResultCode.java +++ b/src/main/java/com/qzx/xdupartner/entity/vo/ResultCode.java @@ -8,6 +8,8 @@ @ApiModel("返回状态结构体") public enum ResultCode implements StatusCode { SUCCESS(1000, "请求成功"), + + LOGIN_UNVALID(2000, "登录过期"), FAILED(2001, "请求失败"), VALIDATE_ERROR(2002, "请求参数有误"), UNKNOWN_ERROR(2003, "未知错误"), diff --git a/src/main/java/com/qzx/xdupartner/intercepter/TokenInterceptor.java b/src/main/java/com/qzx/xdupartner/intercepter/TokenInterceptor.java index 1f9d7b9..cd9f1c3 100644 --- a/src/main/java/com/qzx/xdupartner/intercepter/TokenInterceptor.java +++ b/src/main/java/com/qzx/xdupartner/intercepter/TokenInterceptor.java @@ -4,8 +4,11 @@ import cn.hutool.json.JSONUtil; import com.qzx.xdupartner.constant.RedisConstant; import com.qzx.xdupartner.entity.User; -import com.qzx.xdupartner.entity.vo.R; +import com.qzx.xdupartner.entity.vo.ResultCode; +import com.qzx.xdupartner.util.JwtUtil; +import com.qzx.xdupartner.util.RUtil; import com.qzx.xdupartner.util.UserHolder; +import io.jsonwebtoken.Claims; import lombok.Setter; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component; @@ -15,6 +18,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Objects; +import java.util.concurrent.TimeUnit; @Setter @Component @@ -28,13 +32,26 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons //解析token->从redis拿出User->放入UserHolder if (StrUtil.isNotBlank(token)) { String redisKey = RedisConstant.LOGIN_PREFIX + token; -// String redisKey = RedisConstant.LOGIN_PREFIX + "12345678"; User loginUser = JSONUtil.toBean(stringRedisTemplate.opsForValue().get(redisKey), User.class); if (Objects.isNull(loginUser)) { - response.setStatus(401); - response.setCharacterEncoding("utf-8"); - response.getWriter().write(JSONUtil.toJsonStr(new R(2000, "登录过期", "登录过期"))); - return false; + //todo 为了兼容老逻辑,最后都要切换为jwt + String userid = null; + try { + Claims claims = JwtUtil.parseJWT(token); + userid = claims.getSubject(); + } catch (Exception e) { + response.setStatus(401); + response.getWriter().write(JSONUtil.toJsonStr(RUtil.error(ResultCode.LOGIN_UNVALID))); + return false; + } + redisKey = RedisConstant.LOGIN_PREFIX + userid; + loginUser = JSONUtil.toBean(stringRedisTemplate.opsForValue().get(redisKey), User.class); + if (Objects.isNull(loginUser)) { + response.setStatus(401); + response.getWriter().write(JSONUtil.toJsonStr(RUtil.error(ResultCode.LOGIN_UNVALID))); + return false; + } + stringRedisTemplate.expire(redisKey, RedisConstant.LOGIN_VALID_TTL, TimeUnit.HOURS); } loginUser.setSessionKey(token); UserHolder.saveUser(loginUser); diff --git a/src/main/java/com/qzx/xdupartner/service/impl/MsmServiceImpl.java b/src/main/java/com/qzx/xdupartner/service/impl/MsmServiceImpl.java index bd81b5e..e8bad92 100644 --- a/src/main/java/com/qzx/xdupartner/service/impl/MsmServiceImpl.java +++ b/src/main/java/com/qzx/xdupartner/service/impl/MsmServiceImpl.java @@ -36,7 +36,7 @@ public boolean send(String phone, String verificationCode) { //实例化request封装请求信息 SendSmsRequest request = new SendSmsRequest(); - String[] phoneNumber = {phone}; + String[] phoneNumber = {"+86 " + phone}; request.setPhoneNumberSet(phoneNumber); //设置手机号 request.setSmsSdkAppid(MsmConstantUtils.APP_ID); request.setSign(MsmConstantUtils.SIGN_NAME); @@ -45,7 +45,7 @@ public boolean send(String phone, String verificationCode) { String[] templateParamSet = {verificationCode, "5"}; request.setTemplateParamSet(templateParamSet); - //发送短信 +// 发送短信 SendSmsResponse response = smsClient.SendSms(request); log.info(SendSmsResponse.toJsonString(response)); return true; diff --git a/src/main/java/com/qzx/xdupartner/service/impl/PhoneServiceImpl.java b/src/main/java/com/qzx/xdupartner/service/impl/PhoneServiceImpl.java index 9f300a8..b75898a 100644 --- a/src/main/java/com/qzx/xdupartner/service/impl/PhoneServiceImpl.java +++ b/src/main/java/com/qzx/xdupartner/service/impl/PhoneServiceImpl.java @@ -3,6 +3,7 @@ import cn.hutool.core.util.BooleanUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; import com.qzx.xdupartner.constant.RedisConstant; import com.qzx.xdupartner.entity.User; import com.qzx.xdupartner.entity.dto.PhoneAuthDto; @@ -12,6 +13,7 @@ import com.qzx.xdupartner.service.MsmService; import com.qzx.xdupartner.service.PhoneService; import com.qzx.xdupartner.service.UserService; +import com.qzx.xdupartner.util.JwtUtil; import com.qzx.xdupartner.util.UserUtil; import com.qzx.xdupartner.util.VerifyUtil; import lombok.extern.slf4j.Slf4j; @@ -57,22 +59,27 @@ public LoginVo verifyVerCode(PhoneAuthDto phoneAuthDto) { if (StrUtil.isBlank(vcode) || !vcode.equals(phoneAuthDto.getVerCode())) { throw new APIException(ResultCode.PHONE_VERIFY_ERROR); } - Boolean deleted = stringRedisTemplate.delete(key); - if (!BooleanUtil.isTrue(deleted)) { - throw new APIException(ResultCode.FAILED); - } + //查看库中是否存在手机号 User user = userService.lambdaQuery().eq(User::getPhone, phoneAuthDto.getPhone()).one(); //不存在则创建账号 - if (ObjectUtil.isNotNull(user)) { - user = UserUtil.createUser(user.getPhone(), StrUtil.EMPTY); - } - boolean saved = userService.save(user); - if (!saved) { - throw new APIException(ResultCode.FAILED); + if (ObjectUtil.isNull(user)) { + user = UserUtil.createUser(phoneAuthDto.getPhone(), null); + boolean saved = userService.save(user); + if (!saved) { + throw new APIException(ResultCode.FAILED); + } } + //返回LoginVo //todo 构造token - return new LoginVo().setUserInfoVo(UserUtil.convertToUserInfoVo(user)).setToken(""); + String jwt = JwtUtil.createJWT(user.getId().toString()); + stringRedisTemplate.opsForValue().set(RedisConstant.LOGIN_PREFIX + jwt, JSONUtil.toJsonStr(user), + RedisConstant.LOGIN_VALID_TTL, TimeUnit.HOURS); + Boolean deleted = stringRedisTemplate.delete(key); + if (!BooleanUtil.isTrue(deleted)) { + throw new APIException(ResultCode.FAILED); + } + return new LoginVo().setUserInfoVo(UserUtil.convertToUserInfoVo(user)).setToken(jwt); } } diff --git a/src/main/java/com/qzx/xdupartner/util/JwtUtil.java b/src/main/java/com/qzx/xdupartner/util/JwtUtil.java new file mode 100644 index 0000000..08fa466 --- /dev/null +++ b/src/main/java/com/qzx/xdupartner/util/JwtUtil.java @@ -0,0 +1,128 @@ +package com.qzx.xdupartner.util; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.JwtBuilder; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import lombok.Getter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import java.util.Base64; +import java.util.Date; +import java.util.UUID; + +/** + * JWT工具类 + */ +@Component +public class JwtUtil { + + //有效期为 + public static final Long JWT_TTL = 14 * 24 * 60 * 60 * 1000L;// 60 * 60 *1000 一个小时 + //设置秘钥明文 + @Getter + public static String JWT_KEY = "qzxabc"; + + @Value("${jwt_key}") + public void setJwtKey(String jwtKey) { + JWT_KEY = jwtKey; + } + + public static String getUUID() { + String token = UUID.randomUUID().toString().replaceAll("-", ""); + return token; + } + + /** + * 生成jtw + * + * @param subject token中要存放的数据(json格式) + * @return + */ + public static String createJWT(String subject) { + JwtBuilder builder = getJwtBuilder(subject, null, getUUID());// 设置过期时间 + return builder.compact(); + } + + /** + * 生成jtw + * + * @param subject token中要存放的数据(json格式) + * @param ttlMillis token超时时间 + * @return + */ + public static String createJWT(String subject, Long ttlMillis) { + JwtBuilder builder = getJwtBuilder(subject, ttlMillis, getUUID());// 设置过期时间 + return builder.compact(); + } + + private static JwtBuilder getJwtBuilder(String subject, Long ttlMillis, String uuid) { + SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; + SecretKey secretKey = generalKey(); + long nowMillis = System.currentTimeMillis(); + Date now = new Date(nowMillis); + if (ttlMillis == null) { + ttlMillis = JwtUtil.JWT_TTL; + } + long expMillis = nowMillis + ttlMillis; + Date expDate = new Date(expMillis); + return Jwts.builder() + .setId(uuid) //唯一的ID + .setSubject(subject) // 主题 可以是JSON数据 + .setIssuer("qzx") // 签发者 + .setIssuedAt(now) // 签发时间 + .signWith(signatureAlgorithm, secretKey) //使用HS256对称加密算法签名, 第二个参数为秘钥 + .setExpiration(expDate); + } + + /** + * 创建token + * + * @param id + * @param subject + * @param ttlMillis + * @return + */ + public static String createJWT(String id, String subject, Long ttlMillis) { + JwtBuilder builder = getJwtBuilder(subject, ttlMillis, id);// 设置过期时间 + return builder.compact(); + } + + //for test + public static void main(String[] args) throws Exception { + String token = ""; + Claims claims = parseJWT(token); + System.out.println(claims); + } + + /** + * 生成加密后的秘钥 secretKey + * + * @return + */ + public static SecretKey generalKey() { + byte[] encodedKey = Base64.getDecoder().decode(JwtUtil.JWT_KEY); + SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES"); + return key; + } + + /** + * 解析 + * + * @param jwt + * @return + * @throws Exception + */ + public static Claims parseJWT(String jwt) throws Exception { + SecretKey secretKey = generalKey(); + return Jwts.parser() + .setSigningKey(secretKey) + .parseClaimsJws(jwt) + .getBody(); + } + + +} \ No newline at end of file diff --git a/src/main/java/com/qzx/xdupartner/util/UserUtil.java b/src/main/java/com/qzx/xdupartner/util/UserUtil.java index d7ccf4c..3b461be 100644 --- a/src/main/java/com/qzx/xdupartner/util/UserUtil.java +++ b/src/main/java/com/qzx/xdupartner/util/UserUtil.java @@ -77,11 +77,14 @@ public static UserInfoDto getUserInfoVo(User user) { public static User createUser(String phone, String openid) { User user = new User() .setPhone(phone) - .setOpenId(openid) + .setIcon(SystemConstant.DEFAULT_ICON_URL + RandomUtil.randomInt(SystemConstant.RANDOM_ICON_MIN, SystemConstant.RANDOM_ICON_MAX) + ".png") .setMyDescription("写几句话来描述一下自己吧~"); + if (openid != null) { + user.setOpenId(openid); + } StringRedisTemplate stringRedisTemplate = SpringUtil.getBean(StringRedisTemplate.class); user.setNickName(SystemConstant.DEFAULT_NICKNAME + stringRedisTemplate.opsForValue().increment(RedisConstant.DEFAULT_NICKNAME_INCREMENT));