From 16b20f38cd4cc0b651a655aeb74df198721a135c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=94?= <2393584716@qq.com> Date: Sat, 2 May 2020 15:19:55 +0800 Subject: [PATCH] =?UTF-8?q?v1.0.3=E7=89=88=E6=9C=AC=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sa-token-demo-springboot/pom.xml | 2 +- .../java/com/pj/satoken/MySaTokenConfig.java | 5 ++- .../java/com/pj/satoken/SaTokenDaoRedis.java | 7 +--- .../src/main/java/com/pj/test/AjaxJson.java | 1 - .../main/java/com/pj/test/TestController.java | 1 + .../main/java/com/pj/test/TopController.java | 32 +++++++--------- sa-token-dev/pom.xml | 2 +- .../java/cn/dev33/satoken/SaTokenUtil.java | 6 +-- .../annotation/SaCheckInterceptor.java | 34 +++++++++++++++-- .../dev33/satoken/config/SaTokenConfig.java | 2 +- .../satoken/exception/NotLoginException.java | 26 ++++++++++++- .../exception/NotPermissionException.java | 30 +++++++++++---- .../java/cn/dev33/satoken/stp/StpLogic.java | 38 ++++++++++++++----- .../java/cn/dev33/satoken/stp/StpUtil.java | 15 ++++++++ .../src/main/resources/application.yml | 2 +- sa-token-doc/doc/_sidebar.md | 2 +- sa-token-doc/doc/index.html | 4 +- sa-token-doc/doc/more/link.md | 8 ++-- sa-token-doc/doc/more/update-log.md | 11 +++++- sa-token-doc/doc/start/download.md | 31 ++++++++------- sa-token-doc/doc/start/example.md | 4 +- sa-token-doc/doc/use/at-check.md | 24 +++++++++++- sa-token-doc/doc/use/config.md | 6 +-- sa-token-doc/doc/use/jur-auth.md | 1 + sa-token-doc/doc/use/login-auth.md | 6 +++ sa-token-doc/index.html | 2 +- 26 files changed, 219 insertions(+), 83 deletions(-) diff --git a/sa-token-demo-springboot/pom.xml b/sa-token-demo-springboot/pom.xml index 8a36dcc1..9b65c1fc 100644 --- a/sa-token-demo-springboot/pom.xml +++ b/sa-token-demo-springboot/pom.xml @@ -29,7 +29,7 @@ cn.dev33 sa-token - 1.0.2 + 1.0.3 diff --git a/sa-token-demo-springboot/src/main/java/com/pj/satoken/MySaTokenConfig.java b/sa-token-demo-springboot/src/main/java/com/pj/satoken/MySaTokenConfig.java index cc2c8265..de39f88b 100644 --- a/sa-token-demo-springboot/src/main/java/com/pj/satoken/MySaTokenConfig.java +++ b/sa-token-demo-springboot/src/main/java/com/pj/satoken/MySaTokenConfig.java @@ -18,7 +18,7 @@ public class MySaTokenConfig extends WebMvcConfigurationSupport { // public SaTokenConfig getSaTokenConfig() { // SaTokenConfig config = new SaTokenConfig(); // config.setTokenName("satoken"); // token名称(同时也是cookie名称) -// config.setTimeout(30 * 24 * 60 * 60); // token有效期,单位s 默认30天,-1为永不过期 +// config.setTimeout(30 * 24 * 60 * 60); // token有效期,单位s 默认30天 // config.setIsShare(true); // 在多人登录同一账号时,是否共享会话(为true时共用一个,为false时新登录挤掉旧登录) // config.setIsReadHead(true); // 是否在cookie读取不到token时,继续从请求header里继续尝试读取 // config.setIsReadBody(true); // 是否在cookie读取不到token时,继续从请求header里继续尝试读取 @@ -29,7 +29,8 @@ public class MySaTokenConfig extends WebMvcConfigurationSupport { // 注册sa-token的拦截器,打开注解式鉴权功能 @Override public void addInterceptors(InterceptorRegistry registry) { - registry.addInterceptor(new SaCheckInterceptor()).addPathPatterns("/**"); + registry.addInterceptor(new SaCheckInterceptor()).addPathPatterns("/**"); // 全局拦截器 } + } diff --git a/sa-token-demo-springboot/src/main/java/com/pj/satoken/SaTokenDaoRedis.java b/sa-token-demo-springboot/src/main/java/com/pj/satoken/SaTokenDaoRedis.java index 6909cff1..bc88aa85 100644 --- a/sa-token-demo-springboot/src/main/java/com/pj/satoken/SaTokenDaoRedis.java +++ b/sa-token-demo-springboot/src/main/java/com/pj/satoken/SaTokenDaoRedis.java @@ -6,7 +6,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer; -import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; // import org.springframework.stereotype.Component; @@ -29,10 +28,8 @@ public class SaTokenDaoRedis implements SaTokenDao { @Autowired @SuppressWarnings({ "rawtypes", "unchecked" }) public void setRedisTemplate(RedisTemplate redisTemplate) { - RedisSerializer stringSerializer = new StringRedisSerializer(); - redisTemplate.setKeySerializer(stringSerializer); - JdkSerializationRedisSerializer jrSerializer = new JdkSerializationRedisSerializer(); - redisTemplate.setValueSerializer(jrSerializer); + redisTemplate.setKeySerializer(new StringRedisSerializer()); + redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer()); this.redisTemplate = redisTemplate; } diff --git a/sa-token-demo-springboot/src/main/java/com/pj/test/AjaxJson.java b/sa-token-demo-springboot/src/main/java/com/pj/test/AjaxJson.java index f8c12a10..08accd72 100644 --- a/sa-token-demo-springboot/src/main/java/com/pj/test/AjaxJson.java +++ b/sa-token-demo-springboot/src/main/java/com/pj/test/AjaxJson.java @@ -6,7 +6,6 @@ import java.util.List; /** * ajax返回Json的封装 - * 【此类封装了Meta和Body的功能,写法不同,但是返回数据格式相同】 */ public class AjaxJson implements Serializable{ diff --git a/sa-token-demo-springboot/src/main/java/com/pj/test/TestController.java b/sa-token-demo-springboot/src/main/java/com/pj/test/TestController.java index c8bed11b..2cbf8290 100644 --- a/sa-token-demo-springboot/src/main/java/com/pj/test/TestController.java +++ b/sa-token-demo-springboot/src/main/java/com/pj/test/TestController.java @@ -31,6 +31,7 @@ public class TestController { // System.out.println("当前是否登录:" + StpUtil.isLogin()); // System.out.println("当前登录账号:" + StpUtil.getLoginId_defaultNull()); // StpUtil.setLoginId(id); // 在当前会话登录此账号 +// System.out.println("根据token找登录id:" + StpUtil.getLoginIdByToken(StpUtil.getTokenValue())); System.out.println("当前token信息:" + StpUtil.getTokenInfo()); // 获取登录id并转为int System.out.println("当前登录账号:" + StpUtil.getLoginId_defaultNull()); diff --git a/sa-token-demo-springboot/src/main/java/com/pj/test/TopController.java b/sa-token-demo-springboot/src/main/java/com/pj/test/TopController.java index a31775b2..90e1723a 100644 --- a/sa-token-demo-springboot/src/main/java/com/pj/test/TopController.java +++ b/sa-token-demo-springboot/src/main/java/com/pj/test/TopController.java @@ -17,7 +17,7 @@ import cn.dev33.satoken.exception.NotPermissionException; /** * 加强版控制器 */ -@ControllerAdvice // 可指定包前缀,比如:(basePackages = "com.zyd.blog.controller.admin") +@ControllerAdvice // 可指定包前缀,比如:(basePackages = "com.pj.admin") public class TopController { // 在每个控制器之前触发的操作 @@ -31,27 +31,23 @@ public class TopController { public void handlerException(Exception e, HttpServletRequest request, HttpServletResponse response) throws Exception { - e.printStackTrace(); // 打印堆栈,以供调试 + // 打印堆栈,以供调试 + e.printStackTrace(); - response.setContentType("application/json; charset=utf-8"); // http说明,我要返回JSON对象 - - // 如果是未登录异常 - if (e instanceof NotLoginException) { - String jsonStr = new ObjectMapper().writeValueAsString(AjaxJson.getNotLogin()); - response.getWriter().print(jsonStr); - return; - } - // 如果是权限异常 - if (e instanceof NotPermissionException) { + // 不同异常返回不同状态码 + AjaxJson aj = null; + if (e instanceof NotLoginException) { // 如果是未登录异常 + aj = AjaxJson.getNotLogin(); + } else if(e instanceof NotPermissionException) { // 如果是权限异常 NotPermissionException ee = (NotPermissionException) e; - String jsonStr = new ObjectMapper().writeValueAsString(AjaxJson.getNotJur("无此权限:" + ee.getCode())); - response.getWriter().print(jsonStr); - return; + aj = AjaxJson.getNotJur("无此权限:" + ee.getCode()); + } else { // 普通异常, 输出:500 + 异常信息 + aj = AjaxJson.getError(e.getMessage()); } - // 普通异常输出:500 + 异常信息 - response.getWriter().print(new ObjectMapper().writeValueAsString(AjaxJson.getError(e.getMessage()))); - + // 输出到客户端 + response.setContentType("application/json; charset=utf-8"); // http说明,我要返回JSON对象 + response.getWriter().print(new ObjectMapper().writeValueAsString(aj)); } } diff --git a/sa-token-dev/pom.xml b/sa-token-dev/pom.xml index 8e465295..a152258e 100644 --- a/sa-token-dev/pom.xml +++ b/sa-token-dev/pom.xml @@ -7,7 +7,7 @@ cn.dev33 sa-token-dev jar - 1.0.2 + 1.0.3 diff --git a/sa-token-dev/src/main/java/cn/dev33/satoken/SaTokenUtil.java b/sa-token-dev/src/main/java/cn/dev33/satoken/SaTokenUtil.java index 93590059..7d8c4d04 100644 --- a/sa-token-dev/src/main/java/cn/dev33/satoken/SaTokenUtil.java +++ b/sa-token-dev/src/main/java/cn/dev33/satoken/SaTokenUtil.java @@ -7,7 +7,7 @@ public class SaTokenUtil { // sa-token 版本号 - public static final String version = "v1.0.0"; + public static final String version = "v1.0.3"; // sa-token 开源地址 public static final String github_url = "https://github.com/click33/sa-token"; @@ -23,8 +23,8 @@ public class SaTokenUtil { System.out.println(str); } - // 如果token为本次请求新创建的,则以此字符串为key存储在当前request中 - public static final String just_created_save_key= "just_created_save_key_"; + // 如果token为本次请求新创建的,则以此字符串为key存储在当前request中 JUST_CREATED_SAVE_KEY + public static final String JUST_CREATED_SAVE_KEY= "JUST_CREATED_SAVE_KEY_"; } diff --git a/sa-token-dev/src/main/java/cn/dev33/satoken/annotation/SaCheckInterceptor.java b/sa-token-dev/src/main/java/cn/dev33/satoken/annotation/SaCheckInterceptor.java index 6a9bc440..a360132a 100644 --- a/sa-token-dev/src/main/java/cn/dev33/satoken/annotation/SaCheckInterceptor.java +++ b/sa-token-dev/src/main/java/cn/dev33/satoken/annotation/SaCheckInterceptor.java @@ -6,6 +6,7 @@ import javax.servlet.http.HttpServletResponse; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; +import cn.dev33.satoken.stp.StpLogic; import cn.dev33.satoken.stp.StpUtil; /** @@ -13,6 +14,28 @@ import cn.dev33.satoken.stp.StpUtil; */ public class SaCheckInterceptor implements HandlerInterceptor { + + // 底层的 StpLogic 对象 + public StpLogic stpLogic = null; + + /** + * 创建,并指定一个默认的 StpLogic + */ + public SaCheckInterceptor() { + this(StpUtil.stpLogic); + } + + /** + * 创建,并指定一个的 StpLogic + * @param stpLogic 指定的StpLogic + */ + public SaCheckInterceptor(StpLogic stpLogic) { + this.stpLogic = stpLogic; + } + + + + // 每次请求之前触发 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) @@ -26,7 +49,7 @@ public class SaCheckInterceptor implements HandlerInterceptor { // 验证登录 if(method.hasMethodAnnotation(SaCheckLogin.class) || method.getBeanType().isAnnotationPresent(SaCheckLogin.class)) { - StpUtil.getLoginId(); + stpLogic.checkLogin(); } // 获取权限注解 @@ -41,14 +64,17 @@ public class SaCheckInterceptor implements HandlerInterceptor { // 开始验证权限 Object[] codeArray = concatABC(scp.value(), scp.valueInt(), scp.valueLong()); if(scp.isAnd()) { - StpUtil.checkPermissionAnd(codeArray); // 必须全部都有 + stpLogic.checkPermissionAnd(codeArray); // 必须全部都有 } else { - StpUtil.checkPermissionOr(codeArray); // 有一个就行了 + stpLogic.checkPermissionOr(codeArray); // 有一个就行了 } - + return true; } + + + // 合并三个数组 private Object[] concatABC(String[] a, int[] b, long[] c) { diff --git a/sa-token-dev/src/main/java/cn/dev33/satoken/config/SaTokenConfig.java b/sa-token-dev/src/main/java/cn/dev33/satoken/config/SaTokenConfig.java index f499697b..2d2dd7e2 100644 --- a/sa-token-dev/src/main/java/cn/dev33/satoken/config/SaTokenConfig.java +++ b/sa-token-dev/src/main/java/cn/dev33/satoken/config/SaTokenConfig.java @@ -6,7 +6,7 @@ package cn.dev33.satoken.config; public class SaTokenConfig { private String tokenName = "satoken"; // token名称(同时也是cookie名称) - private long timeout = 30 * 24 * 60 * 60; // token有效期,单位s 默认30天,-1为永不过期 + private long timeout = 30 * 24 * 60 * 60; // token有效期,单位s 默认30天 private Boolean isShare = true; // 在多人登录同一账号时,是否共享会话(为true时共用一个,为false时新登录挤掉旧登录) private Boolean isReadHead = true; // 是否在cookie读取不到token时,继续从请求header里继续尝试读取 private Boolean isReadBody = true; // 是否在header读取不到token时,继续从请求题参数里继续尝试读取 diff --git a/sa-token-dev/src/main/java/cn/dev33/satoken/exception/NotLoginException.java b/sa-token-dev/src/main/java/cn/dev33/satoken/exception/NotLoginException.java index a9d67c84..836e9d67 100644 --- a/sa-token-dev/src/main/java/cn/dev33/satoken/exception/NotLoginException.java +++ b/sa-token-dev/src/main/java/cn/dev33/satoken/exception/NotLoginException.java @@ -1,5 +1,7 @@ package cn.dev33.satoken.exception; +import cn.dev33.satoken.stp.StpUtil; + /** * 没有登陆抛出的异常 */ @@ -9,13 +11,35 @@ public class NotLoginException extends RuntimeException { * */ private static final long serialVersionUID = 6806129545290130142L; + + + /** + * login_key + */ + private String login_key; + /** + * 获得login_key + * @return login_key + */ + public String getLoginKey() { + return login_key; + } + /** * 创建一个 */ public NotLoginException() { - super("当前账号未登录"); + this(StpUtil.stpLogic.login_key); } + /** + * 创建一个 + * @param login_key login_key + */ + public NotLoginException(String login_key) { + super("当前会话未登录"); // 这里到底要不要拼接上login_key呢?纠结 + this.login_key = login_key; + } } diff --git a/sa-token-dev/src/main/java/cn/dev33/satoken/exception/NotPermissionException.java b/sa-token-dev/src/main/java/cn/dev33/satoken/exception/NotPermissionException.java index d7d4d221..3055775c 100644 --- a/sa-token-dev/src/main/java/cn/dev33/satoken/exception/NotPermissionException.java +++ b/sa-token-dev/src/main/java/cn/dev33/satoken/exception/NotPermissionException.java @@ -1,5 +1,7 @@ package cn.dev33.satoken.exception; +import cn.dev33.satoken.stp.StpUtil; + /** * 没有指定权限码,抛出的异常 */ @@ -10,24 +12,38 @@ public class NotPermissionException extends RuntimeException { */ private static final long serialVersionUID = 6806129545290130142L; + /** + * 权限码 + */ private Object code; - - /** * @return 获得权限码 */ public Object getCode() { return code; } + + /** + * login_key + */ + private String login_key; + /** + * 获得login_key + * @return login_key + */ + public String getLoginKey() { + return login_key; + } + public NotPermissionException(Object code) { - super("无此权限:" + code); + this(code, StpUtil.stpLogic.login_key); + } + public NotPermissionException(Object code, String login_key) { + super("无此权限:" + code); // 这里到底要不要拼接上login_key呢?纠结 this.code = code; + this.login_key = login_key; } -// public NotPermissionException(Object code, String s) { -// super(s); -// this.code = code; -// } } diff --git a/sa-token-dev/src/main/java/cn/dev33/satoken/stp/StpLogic.java b/sa-token-dev/src/main/java/cn/dev33/satoken/stp/StpLogic.java index 3f7f5bec..a2968ad7 100644 --- a/sa-token-dev/src/main/java/cn/dev33/satoken/stp/StpLogic.java +++ b/sa-token-dev/src/main/java/cn/dev33/satoken/stp/StpLogic.java @@ -27,7 +27,7 @@ import cn.dev33.satoken.util.SpringMVCUtil; public class StpLogic { - private String login_key = ""; // 持久化的key前缀,多账号体系时以此值区分,比如:login、user、admin + public String login_key = ""; // 持久化的key前缀,多账号体系时以此值区分,比如:login、user、admin public StpLogic(String login_key) { this.login_key = login_key; @@ -55,8 +55,8 @@ public class StpLogic { String key_tokenName = getKey_tokenName(); // 1、尝试从request里读取 - if(request.getAttribute(SaTokenUtil.just_created_save_key) != null) { - return String.valueOf(request.getAttribute(SaTokenUtil.just_created_save_key)); + if(request.getAttribute(SaTokenUtil.JUST_CREATED_SAVE_KEY) != null) { + return String.valueOf(request.getAttribute(SaTokenUtil.JUST_CREATED_SAVE_KEY)); } // 2、尝试从cookie里读取 @@ -137,7 +137,7 @@ public class StpLogic { // 3、持久化 dao.setValue(getKey_TokenValue(tokenValue), String.valueOf(login_id), config.getTimeout()); // token -> uid dao.setValue(getKey_LoginId(login_id), tokenValue, config.getTimeout()); // uid -> token - request.setAttribute(SaTokenUtil.just_created_save_key, tokenValue); // 保存到本次request里 + request.setAttribute(SaTokenUtil.JUST_CREATED_SAVE_KEY, tokenValue); // 保存到本次request里 SaCookieUtil.addCookie(SpringMVCUtil.getResponse(), getKey_tokenName(), tokenValue, "/", (int)config.getTimeout()); // cookie注入 } @@ -180,7 +180,14 @@ public class StpLogic { public boolean isLogin() { return getLoginId_defaultNull() != null; } - + + /** + * 检验当前会话是否已经登录,如未登录,则抛出异常 + */ + public void checkLogin() { + getLoginId(); + } + /** * 获取当前会话登录id, 如果未登录,则抛出异常 * @return @@ -188,7 +195,7 @@ public class StpLogic { public Object getLoginId() { Object login_id = getLoginId_defaultNull(); if(login_id == null) { - throw new NotLoginException(); + throw new NotLoginException(this.login_key); } return login_id; } @@ -263,6 +270,19 @@ public class StpLogic { return Long.valueOf(String.valueOf(getLoginId())); } + /** + * 获取指定token对应的登录id,如果未登录,则返回 null + * @return + */ + public Object getLoginIdByToken(String tokenValue) { + if(tokenValue != null) { + Object login_id = SaTokenManager.getDao().getValue(getKey_TokenValue(tokenValue)); + if(login_id != null) { + return login_id; + } + } + return null; + } // =================== session相关 =================== @@ -329,7 +349,7 @@ public class StpLogic { */ public void checkPermission(Object pcode) { if(hasPermission(pcode) == false) { - throw new NotPermissionException(pcode); + throw new NotPermissionException(pcode, this.login_key); } } @@ -342,7 +362,7 @@ public class StpLogic { List pcodeList = SaTokenManager.getStp().getPermissionCodeList(login_id, login_key); for (Object pcode : pcodeArray) { if(pcodeList.contains(pcode) == false) { - throw new NotPermissionException(pcode); // 没有权限抛出异常 + throw new NotPermissionException(pcode, this.login_key); // 没有权限抛出异常 } } } @@ -360,7 +380,7 @@ public class StpLogic { } } if(pcodeArray.length > 0) { - throw new NotPermissionException(pcodeArray[0]); // 没有权限抛出异常 + throw new NotPermissionException(pcodeArray[0], this.login_key); // 没有权限抛出异常 } } diff --git a/sa-token-dev/src/main/java/cn/dev33/satoken/stp/StpUtil.java b/sa-token-dev/src/main/java/cn/dev33/satoken/stp/StpUtil.java index 3803472f..c44d04ca 100644 --- a/sa-token-dev/src/main/java/cn/dev33/satoken/stp/StpUtil.java +++ b/sa-token-dev/src/main/java/cn/dev33/satoken/stp/StpUtil.java @@ -79,6 +79,13 @@ public class StpUtil { return stpLogic.isLogin(); } + /** + * 检验当前会话是否已经登录,如未登录,则抛出异常 + */ + public static void checkLogin() { + getLoginId(); + } + /** * 获取当前会话登录id, 如果未登录,则抛出异常 * @return @@ -128,6 +135,14 @@ public class StpUtil { return stpLogic.getLoginId_asLong(); } + /** + * 获取指定token对应的登录id,如果未登录,则返回 null + * @return + */ + public static Object getLoginIdByToken(String tokenValue) { + return stpLogic.getLoginIdByToken(tokenValue); + } + // =================== session相关 =================== /** diff --git a/sa-token-dev/src/main/resources/application.yml b/sa-token-dev/src/main/resources/application.yml index 36a3adec..835fdf29 100644 --- a/sa-token-dev/src/main/resources/application.yml +++ b/sa-token-dev/src/main/resources/application.yml @@ -7,7 +7,7 @@ spring: sa-token: # token名称(同时也是cookie名称) token-name: satoken - # token有效期,单位s 默认30天,-1为永不过期 + # token有效期,单位s 默认30天 timeout: 2592000 # 在多人登录同一账号时,是否共享会话(为true时共用一个,为false时新登录挤掉旧登录) is-share: true diff --git a/sa-token-doc/doc/_sidebar.md b/sa-token-doc/doc/_sidebar.md index a592e505..67833703 100644 --- a/sa-token-doc/doc/_sidebar.md +++ b/sa-token-doc/doc/_sidebar.md @@ -2,7 +2,7 @@ - **开始** - [介绍](/README) - - [下载](/start/download) + - [集成](/start/download) - [示例](/start/example) - **使用** diff --git a/sa-token-doc/doc/index.html b/sa-token-doc/doc/index.html index 67dc459a..18ae5900 100644 --- a/sa-token-doc/doc/index.html +++ b/sa-token-doc/doc/index.html @@ -66,13 +66,13 @@
加载中...