package com.xcong.farmer.cms.modules.system.service.Impl; import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.asymmetric.KeyType; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.xcong.farmer.cms.common.contants.AppContants; import com.xcong.farmer.cms.common.response.Result; import com.xcong.farmer.cms.configurations.properties.ApplicationProperties; import com.xcong.farmer.cms.configurations.properties.SecurityProperties; import com.xcong.farmer.cms.modules.system.dto.AdminLoginDto; import com.xcong.farmer.cms.modules.system.entity.UserEntity; import com.xcong.farmer.cms.modules.system.mapper.UserMapper; import com.xcong.farmer.cms.modules.system.service.ICommonService; import com.xcong.farmer.cms.modules.system.util.CaptchaUtil; import com.xcong.farmer.cms.modules.system.util.LoginUserUtil; import com.xcong.farmer.cms.modules.system.util.UUIDUtil; import com.xcong.farmer.cms.utils.RedisUtils; import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ValueOperations; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.annotation.Resource; import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.crypto.asymmetric.RSA; @Service @Slf4j public class CommonServiceImpl extends ServiceImpl implements ICommonService { @Resource private UserMapper userMapper; @Resource private RedisUtils redisUtils; @Resource private ApplicationProperties applicationProperties; @Resource private SecurityProperties securityProperties; @Autowired private RedisTemplate redisTemplate; @Autowired private UUIDUtil uuidUtil; @Autowired private CaptchaUtil captchaUtil; //从SpringBoot的配置文件中取出过期时间 @Value("${server.servlet.session.timeout}") private Integer timeout; @Override public Result login(AdminLoginDto adminLoginDto) { //根据前端传回的token在redis中找对应的value ValueOperations valueOperations = redisTemplate.opsForValue(); String codeToken = adminLoginDto.getCodeToken(); String codeValue = adminLoginDto.getCodeValue(); if (redisTemplate.hasKey(codeToken)) { //验证通过, 删除对应的key if (valueOperations.get(codeToken).equals(codeValue)) { redisTemplate.delete(codeToken); } else { return Result.fail("验证码不正确"); } } else { return Result.fail("验证码已过期"); } String username = adminLoginDto.getUsername(); String password = adminLoginDto.getPassword(); UserEntity userEntity = userMapper.selectByUserNameAndPassword(username, SecureUtil.md5(password)); if(ObjectUtil.isEmpty(userEntity)){ return Result.fail("请输入正确的账号和密码"); } Integer status = userEntity.getStatus(); if(UserEntity.STATUS_DISABLED.equals(status)){ return Result.fail("账号禁止登陆,请联系管理员"); } //生成UUID作为token String token = IdUtil.simpleUUID(); String redisToken = AppContants.APP_LOGIN_PREFIX + token; String redisMember = AppContants.APP_LOGIN_PREFIX + userEntity.getId(); if (StrUtil.isNotBlank(redisUtils.getString(redisMember))) { redisUtils.del(AppContants.APP_LOGIN_PREFIX + redisUtils.getString(redisMember)); } redisUtils.set(redisToken, JSONObject.toJSONString(userEntity), 3000L); redisUtils.set(redisMember, token); Map authInfo = new HashMap<>(); // 开启debug模式,则将加密后的token返回 if (applicationProperties.isDebug()) { authInfo.put("token", token); authInfo.put("rsaToken", AppContants.TOKEN_START_WITH + generateAsaToken(token)); authInfo.put("user", userEntity); } else { authInfo.put("token", token); authInfo.put("user", userEntity); } return Result.ok("登录成功", authInfo); } @Override public Result memberLogout() { Long id = LoginUserUtil.getLoginUser().getId(); //获取用户ID UserEntity userEntity = userMapper.selectById(id); if (ObjectUtil.isEmpty(userEntity)) { return Result.fail("用户不存在"); } String redisMember = AppContants.APP_LOGIN_PREFIX + userEntity.getId(); String token = redisUtils.getString(redisMember); redisUtils.del(AppContants.APP_LOGIN_PREFIX + token); SecurityContextHolder.clearContext(); return Result.ok("退出成功"); } @Override public Map createToken(String captcha) { //生成一个token String key = uuidUtil.getUUID32(); //生成验证码对应的token 以token为key 验证码为value存在redis中 ValueOperations valueOperations = redisTemplate.opsForValue(); valueOperations.set(key, captcha); //设置验证码过期时间 redisTemplate.expire(key, timeout, TimeUnit.MINUTES); Map map = new HashMap<>(); map.put("token", key); map.put("expire", timeout); return map; } @Override public Result captchaCreator() throws IOException { return captchaUtil.catchaImgCreator(); } public String generateAsaToken(String token) { RSA rsa = new RSA(null, securityProperties.getPublicKey()); return rsa.encryptBase64(token + "_" + System.currentTimeMillis(), KeyType.PublicKey); } }