From 696916b19427668d23075727c48ea2746401a303 Mon Sep 17 00:00:00 2001 From: wxl <727869402@qq.com> Date: Sun, 22 Dec 2024 23:39:26 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E7=A7=BB=E5=8A=A8=E7=AB=AF?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E6=8B=A6=E6=88=AA=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/dd/admin/business/api/AuthApi.java | 57 +++++++++++++++++ .../security/interceptor/ApiInterceptor.java | 62 +++++++++++++++++++ .../security/jwt/config/SecurityConfig.java | 9 +++ .../com/dd/admin/common/utils/RedisUtil.java | 1 + src/main/resources/application-online.yml | 2 +- src/main/resources/application.yml | 3 + 6 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/dd/admin/business/api/AuthApi.java create mode 100644 src/main/java/com/dd/admin/common/security/interceptor/ApiInterceptor.java create mode 100644 src/main/java/com/dd/admin/common/utils/RedisUtil.java diff --git a/src/main/java/com/dd/admin/business/api/AuthApi.java b/src/main/java/com/dd/admin/business/api/AuthApi.java new file mode 100644 index 0000000..348f5ed --- /dev/null +++ b/src/main/java/com/dd/admin/business/api/AuthApi.java @@ -0,0 +1,57 @@ +package com.dd.admin.business.api; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.dd.admin.business.note.domain.NoteDto; +import com.dd.admin.business.note.domain.NoteVo; +import com.dd.admin.common.aop.operationLog.aop.OperLog; +import com.dd.admin.common.aop.operationLog.aop.OperType; +import com.dd.admin.common.exception.ApiException; +import com.dd.admin.common.model.result.ResultBean; +import com.dd.admin.common.utils.RedisUtil; +import com.dd.admin.common.utils.StringUtil; +import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class AuthApi { + + @Autowired + RedisUtil redisUtil; + + @ApiOperation(value = "获取验证码") + @ApiOperationSupport(order = 1) + @GetMapping("/api/auth/getCode") + @OperLog(operModule = "获取验证码",operType = OperType.QUERY,operDesc = "获取验证码") + public ResultBean page(String phoneNumber) { + String code = sendSmsCode(phoneNumber); + return ResultBean.success(code); + } + + + + public String sendSmsCode(String phoneNumber) { + String redisKey = "SMS_CODE" + phoneNumber; + String smsCode = String.valueOf(redisUtil.get(redisKey)); + if(StringUtil.isNotEmpty(smsCode)){ + throw new ApiException("验证码已发送,请稍后再试" + smsCode); + } + String code = StringUtil.createCode(4); + //设置有效时间 +// String json = JavaSmsApi.tplSingleSend(phoneNumber,CODE_TPL_ID, BeanUtil.beanToMap(new SmsCode(code))); + +// Map dataMap = (Map) JSON.parse(json); +// if(dataMap.get("msg").equals("发送成功")){ + if(true){ + System.out.println(code); + redisUtil.set(redisKey,code,120); + return code; + }else{ + throw new ApiException("发送失败"); +// throw new ApiException("发送失败,"+dataMap.get("msg")); + } + } + +} diff --git a/src/main/java/com/dd/admin/common/security/interceptor/ApiInterceptor.java b/src/main/java/com/dd/admin/common/security/interceptor/ApiInterceptor.java new file mode 100644 index 0000000..5347d59 --- /dev/null +++ b/src/main/java/com/dd/admin/common/security/interceptor/ApiInterceptor.java @@ -0,0 +1,62 @@ +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.ModelAndView; + +public class ApiInterceptor implements HandlerInterceptor { + + private final JwtUserDetailsService jwtUserDetailsService; + + public ApiInterceptor(JwtUserDetailsService jwtUserDetailsService) { + this.jwtUserDetailsService = jwtUserDetailsService; + } + + @Override + public boolean preIntercept(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + // 获取请求路径,判断是否是以/api开头 + String requestUri = request.getRequestURI(); + if (requestUri.startsWith("/api")) { + // 在这里编写验证手机号和验证码的逻辑,比如从请求参数或者请求头中获取相关信息进行验证 + // 假设从请求参数中获取手机号和验证码,示例代码如下(实际情况可能需要根据具体业务从合适的地方获取) + String phone = request.getParameter("phone"); + String verificationCode = request.getParameter("verificationCode"); + if (isPhoneValid(phone) && isVerificationCodeValid(verificationCode)) { + // 根据验证通过的手机号等信息获取对应的用户详情(这里假设你的用户详情是通过JwtUserDetailsService来获取,实际可能需要根据具体业务调整) + UserDetails userDetails = jwtUserDetailsService.loadUserByUsername(phone); + // 创建认证对象,将用户详情放入其中,这里假设认证方式是基于用户名密码形式(可根据实际调整) + Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); + // 将认证对象放入SecurityContextHolder中,模拟用户已认证的状态 + SecurityContextHolder.getContext().setAuthentication(authentication); + return true; // 验证通过,放行请求 + } else { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // 设置未授权状态码 + return false; // 验证不通过,拦截请求 + } + } + return true; // 如果不是/api开头的请求,直接放行 + } + + private boolean isPhoneValid(String phone) { + // 这里编写手机号验证的具体逻辑,比如正则表达式验证手机号格式是否正确等 + return true; // 示例先返回true,实际需完善逻辑 + } + + private boolean isVerificationCodeValid(String verificationCode) { + // 这里编写验证码验证的具体逻辑,比如和后台存储的验证码进行比对等 + return true; // 示例先返回true,实际需完善逻辑 + } + + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { + HandlerInterceptor.super.postHandle(request, response, handler, modelAndView); + } + + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { + HandlerInterceptor.super.afterCompletion(request, response, handler, ex); + } +} \ No newline at end of file diff --git a/src/main/java/com/dd/admin/common/security/jwt/config/SecurityConfig.java b/src/main/java/com/dd/admin/common/security/jwt/config/SecurityConfig.java index 5a05ec6..4ca09c3 100644 --- a/src/main/java/com/dd/admin/common/security/jwt/config/SecurityConfig.java +++ b/src/main/java/com/dd/admin/common/security/jwt/config/SecurityConfig.java @@ -16,6 +16,7 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.firewall.DefaultHttpFirewall; import org.springframework.security.web.firewall.HttpFirewall; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; /** * SecurityConfig 配置类 @@ -84,4 +85,12 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { // 忽略 所有方法 ignoreConfig.getPattern().forEach(url -> and.ignoring().antMatchers(url)); } + + + // 注册拦截器的方法 + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(new ApiInterceptor()) + .addPathPatterns("/api/**"); // 拦截/api下所有请求路径 + } } diff --git a/src/main/java/com/dd/admin/common/utils/RedisUtil.java b/src/main/java/com/dd/admin/common/utils/RedisUtil.java new file mode 100644 index 0000000..ec14fb8 --- /dev/null +++ b/src/main/java/com/dd/admin/common/utils/RedisUtil.java @@ -0,0 +1 @@ +package com.dd.admin.common.utils; import cn.hutool.core.collection.CollectionUtil; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import javax.annotation.Resource; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; @Component public class RedisUtil { @Resource private RedisTemplate redisTemplate; public Set keys(String keys){ try { return redisTemplate.keys(keys); }catch (Exception e){ e.printStackTrace(); return null; } } /** * 指定缓存失效时间 * @param key 键 * @param time 时间(秒) * @return */ public boolean expire(String key, long time) { try { if (time > 0) { redisTemplate.expire(key, time, TimeUnit.SECONDS); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 根据key 获取过期时间 * @param key 键 不能为null * @return 时间(秒) 返回0代表为永久有效 */ public long getExpire(String key) { return redisTemplate.getExpire(key, TimeUnit.SECONDS); } /** * 判断key是否存在 * @param key 键 * @return true 存在 false不存在 */ public boolean hasKey(String key) { try { return redisTemplate.hasKey(key); } catch (Exception e) { e.printStackTrace(); return false; } } /** * 删除缓存 * @param key 可以传一个值 或多个 */ @SuppressWarnings("unchecked") public void del(String... key) { if (key != null && key.length > 0) { if (key.length == 1) { redisTemplate.delete(key[0]); } else { redisTemplate.delete((Collection) CollectionUtils.arrayToList(key)); } } } /** * 普通缓存获取 * @param key 键 * @return 值 */ public Object get(String key) { return key == null ? null : redisTemplate.opsForValue().get(key); } /** * 普通缓存放入 * @param key 键 * @param value 值 * @return true成功 false失败 */ public boolean set(String key, Object value) { try { redisTemplate.opsForValue().set(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 普通缓存放入并设置时间 * @param key 键 * @param value 值 * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 * @return true成功 false 失败 */ public boolean set(String key, Object value, long time) { try { if (time > 0) { redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); } else { set(key, value); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 递增 * @param key 键 * @param delta 要增加几(大于0) * @return */ public long incr(String key, long delta) { if (delta < 0) { throw new RuntimeException("递增因子必须大于0"); } return redisTemplate.opsForValue().increment(key, delta); } /** * 递减 * @param key 键 * @param delta 要减少几(小于0) * @return */ public long decr(String key, long delta) { if (delta < 0) { throw new RuntimeException("递减因子必须大于0"); } return redisTemplate.opsForValue().increment(key, -delta); } /** * HashGet * @param key 键 不能为null * @param item 项 不能为null * @return 值 */ public Object hget(String key, String item) { return redisTemplate.opsForHash().get(key, item); } /** * 获取hashKey对应的所有键值 * @param key 键 * @return 对应的多个键值 */ public Map hmget(String key) { return redisTemplate.opsForHash().entries(key); } /** * HashSet * @param key 键 * @param map 对应多个键值 * @return true 成功 false 失败 */ public boolean hmset(String key, Map map) { try { redisTemplate.opsForHash().putAll(key, map); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * HashSet 并设置时间 * @param key 键 * @param map 对应多个键值 * @param time 时间(秒) * @return true成功 false失败 */ public boolean hmset(String key, Map map, long time) { try { redisTemplate.opsForHash().putAll(key, map); if (time > 0) { expire(key, time); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 向一张hash表中放入数据,如果不存在将创建 * @param key 键 * @param item 项 * @param value 值 * @return true 成功 false失败 */ public boolean hset(String key, String item, Object value) { try { redisTemplate.opsForHash().put(key, item, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 向一张hash表中放入数据,如果不存在将创建 * @param key 键 * @param item 项 * @param value 值 * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 * @return true 成功 false失败 */ public boolean hset(String key, String item, Object value, long time) { try { redisTemplate.opsForHash().put(key, item, value); if (time > 0) { expire(key, time); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 删除hash表中的值 * @param key 键 不能为null * @param item 项 可以使多个 不能为null */ public void hdel(String key, Object... item) { redisTemplate.opsForHash().delete(key, item); } /** * 判断hash表中是否有该项的值 * @param key 键 不能为null * @param item 项 不能为null * @return true 存在 false不存在 */ public boolean hHasKey(String key, String item) { return redisTemplate.opsForHash().hasKey(key, item); } /** * hash递增 如果不存在,就会创建一个 并把新增后的值返回 * @param key 键 * @param item 项 * @param by 要增加几(大于0) * @return */ public double hincr(String key, String item, double by) { return redisTemplate.opsForHash().increment(key, item, by); } /** * hash递减 * @param key 键 * @param item 项 * @param by 要减少记(小于0) * @return */ public double hdecr(String key, String item, double by) { return redisTemplate.opsForHash().increment(key, item, -by); } /** * 根据key获取Set中的所有值 * @param key 键 * @return */ public Set sGet(String key) { try { return redisTemplate.opsForSet().members(key); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 根据value从一个set中查询,是否存在 * @param key 键 * @param value 值 * @return true 存在 false不存在 */ public boolean sHasKey(String key, Object value) { try { return redisTemplate.opsForSet().isMember(key, value); } catch (Exception e) { e.printStackTrace(); return false; } } /** * 将数据放入set缓存 * @param key 键 * @param values 值 可以是多个 * @return 成功个数 */ public long sSet(String key, Object... values) { try { return redisTemplate.opsForSet().add(key, values); } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 将set数据放入缓存 * @param key 键 * @param time 时间(秒) * @param values 值 可以是多个 * @return 成功个数 */ public long sSetAndTime(String key, long time, Object... values) { try { Long count = redisTemplate.opsForSet().add(key, values); if (time > 0) expire(key, time); return count; } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 获取set缓存的长度 * @param key 键 * @return */ public long sGetSetSize(String key) { try { return redisTemplate.opsForSet().size(key); } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 移除值为value的 * @param key 键 * @param values 值 可以是多个 * @return 移除的个数 */ public long setRemove(String key, Object... values) { try { Long count = redisTemplate.opsForSet().remove(key, values); return count; } catch (Exception e) { e.printStackTrace(); return 0; } } // ===============================list================================= /** * 获取list缓存的内容 * @param key 键 * @param start 开始 * @param end 结束 0 到 -1代表所有值 * @return */ public List lGet(String key, long start, long end) { try { return redisTemplate.opsForList().range(key, start, end); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 获取list缓存的长度 * @param key 键 * @return */ public long lGetListSize(String key) { try { return redisTemplate.opsForList().size(key); } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 通过索引 获取list中的值 * @param key 键 * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 * @return */ public Object lGetIndex(String key, long index) { try { return redisTemplate.opsForList().index(key, index); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 将list放入缓存 * @param key 键 * @param value 值 * @return */ public boolean lSet(String key, Object value) { try { redisTemplate.opsForList().rightPush(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 将list放入缓存 * @param key 键 * @param value 值 * @param time 时间(秒) * @return */ public boolean lSet(String key, Object value, long time) { try { redisTemplate.opsForList().rightPush(key, value); if (time > 0) expire(key, time); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 将list放入缓存 * @param key 键 * @param value 值 * @return */ public boolean lSet(String key, List value) { try { redisTemplate.opsForList().rightPushAll(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 将list放入缓存 * * @param key 键 * @param value 值 * @param time 时间(秒) * @return */ public boolean lSet(String key, List value, long time) { try { redisTemplate.opsForList().rightPushAll(key, value); if (time > 0) expire(key, time); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 根据索引修改list中的某条数据 * @param key 键 * @param index 索引 * @param value 值 * @return */ public boolean lUpdateIndex(String key, long index, Object value) { try { redisTemplate.opsForList().set(key, index, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 移除N个值为value * @param key 键 * @param count 移除多少个 * @param value 值 * @return 移除的个数 */ public long lRemove(String key, long count, Object value) { try { Long remove = redisTemplate.opsForList().remove(key, count, value); return remove; } catch (Exception e) { e.printStackTrace(); return 0; } } } \ No newline at end of file diff --git a/src/main/resources/application-online.yml b/src/main/resources/application-online.yml index e07ffa4..c83dcf8 100644 --- a/src/main/resources/application-online.yml +++ b/src/main/resources/application-online.yml @@ -7,7 +7,7 @@ spring: datasource: driver-class-name: com.p6spy.engine.spy.P6SpyDriver - url: jdbc:p6spy:mysql://127.0.0.1:3306/ddxhs?useSSL=false&autoReconnect=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8 + url: jdbc:p6spy:mysql://8.146.211.120:3306/ddxhs?useSSL=false&autoReconnect=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8 username: root password: wxlwxl12 diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 188b155..54ce6cf 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -38,6 +38,7 @@ jwt: - "/api/**" - "/appUpload/**" - "/upload/**" + - "/appUpload/**" - "/doc.html" - "/swagger-resources/**" - "/v2/api-docs/**" @@ -52,3 +53,5 @@ mybatis-plus: # log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #================================================= mybatis-plus end =================================================== +server: + port: 8080 \ No newline at end of file