一、跨域
1、跨域请求:通过一个域的JavaScript脚本和另外一个域的内容进行交互
2、域的信息:协议、域名、端口号
3、同域:当两个域的协议、域名、端口号均相同
4、解决办法
①在controller上添加@CrossOrigin注解
②添加配置类配置跨域请求
@Component
public class WebMvcConfiguration implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 添加路径规则
.allowCredentials(true) // 是否允许在跨域的情况下传递Cookie
.allowedOriginPatterns("*") // 允许请求来源的域规则
.allowedMethods("*")
.allowedHeaders("*") ; // 允许所有的请求头
}
}
二、图片验证码的后端代码实现
1、创建实体类
@Data
public class ValidateCodeVo {
private String codeKey ; // 验证码的key
private String codeValue ; // 图片验证码对应的字符串数据
}
@Data
public class LoginDto {
private String userName ;
private String password ;
private String captcha ;
private String codeKey ;
}
2、controller层代码
@Autowired
private ValidateCodeService validateCodeService;
@GetMapping(value = "/generateValidateCode")
public Result<ValidateCodeVo> generateValidateCode() {
ValidateCodeVo validateCodeVo = validateCodeService.generateValidateCode();
return Result.build(validateCodeVo , ResultCodeEnum.SUCCESS) ;
}
3、service层代码已经进行redis缓存验证码操作
public interface ValidateCodeService {
// 获取验证码图片
public abstract ValidateCodeVo generateValidateCode();
}
// com.atguigu.spzx.manager.service.impl
@Service
public class ValidateCodeServiceImpl implements ValidateCodeService {
@Autowired
private RedisTemplate<String , String> redisTemplate ;
@Override
public ValidateCodeVo generateValidateCode() {
// 使用hutool工具包中的工具类生成图片验证码
//参数:宽 高 验证码位数 干扰线数量
CircleCaptcha circleCaptcha = CaptchaUtil.createCircleCaptcha(150, 48, 4, 20);
String codeValue = circleCaptcha.getCode();
String imageBase64 = circleCaptcha.getImageBase64();
// 生成uuid作为图片验证码的key
String codeKey = UUID.randomUUID().toString().replace("-", "");
// 将验证码存储到Redis中
redisTemplate.opsForValue().set("user:login:validatecode:" + codeKey , codeValue , 5 , TimeUnit.MINUTES);
// 构建响应结果数据
ValidateCodeVo validateCodeVo = new ValidateCodeVo() ;
validateCodeVo.setCodeKey(codeKey);
validateCodeVo.setCodeValue("data:image/png;base64," + imageBase64);
// 返回数据
return validateCodeVo;
}
@Override
public LoginVo login(LoginDto loginDto) {
// 校验验证码是否正确
String captcha = loginDto.getCaptcha(); // 用户输入的验证码
String codeKey = loginDto.getCodeKey(); // redis中验证码的数据key
// 从Redis中获取验证码
String redisCode = redisTemplate.opsForValue().get("user:login:validatecode:" + codeKey);
if(StrUtil.isEmpty(redisCode) || !StrUtil.equalsIgnoreCase(redisCode , captcha)) {
throw new GuiguException(ResultCodeEnum.VALIDATECODE_ERROR) ;
}
// 验证通过删除redis中的验证码
redisTemplate.delete("user:login:validatecode:" + codeKey) ;
}
}