From 857e260a0a253687120016256d5b4405cc114c37 Mon Sep 17 00:00:00 2001 From: shengzhang <2393584716@qq.com> Date: Sun, 10 Jan 2021 18:36:35 +0800 Subject: [PATCH] =?UTF-8?q?jwt=E9=9B=86=E6=88=90=E7=A4=BA=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../satoken/exception/SaTokenException.java | 8 + .../java/cn/dev33/satoken/stp/StpLogic.java | 26 +- sa-token-demo-jwt/.gitignore | 12 + sa-token-demo-jwt/pom.xml | 80 +++++++ .../com/pj/SaTokenJwtDemoApplication.java | 16 ++ .../com/pj/satoken/jwt/SaTokenJwtUtil.java | 225 ++++++++++++++++++ .../java/com/pj/test/GlobalException.java | 100 ++++++++ .../java/com/pj/test/TestJwtController.java | 60 +++++ .../src/main/java/com/pj/util/AjaxJson.java | 162 +++++++++++++ .../src/main/resources/application.yml | 45 ++++ sa-token-doc/doc/index.html | 2 +- sa-token-doc/index.html | 2 +- .../cn/dev33/satoken/aop/SaCheckAspect.java | 18 +- 13 files changed, 737 insertions(+), 19 deletions(-) create mode 100644 sa-token-demo-jwt/.gitignore create mode 100644 sa-token-demo-jwt/pom.xml create mode 100644 sa-token-demo-jwt/src/main/java/com/pj/SaTokenJwtDemoApplication.java create mode 100644 sa-token-demo-jwt/src/main/java/com/pj/satoken/jwt/SaTokenJwtUtil.java create mode 100644 sa-token-demo-jwt/src/main/java/com/pj/test/GlobalException.java create mode 100644 sa-token-demo-jwt/src/main/java/com/pj/test/TestJwtController.java create mode 100644 sa-token-demo-jwt/src/main/java/com/pj/util/AjaxJson.java create mode 100644 sa-token-demo-jwt/src/main/resources/application.yml diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/exception/SaTokenException.java b/sa-token-core/src/main/java/cn/dev33/satoken/exception/SaTokenException.java index a90a540b..00e77255 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/exception/SaTokenException.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/exception/SaTokenException.java @@ -21,5 +21,13 @@ public class SaTokenException extends RuntimeException { super(message); } + /** + * 构建一个异常 + * @param cause 异常对象 + */ + public SaTokenException(Throwable cause) { + super(cause); + } + } diff --git a/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java b/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java index ab2ea02d..80c69e6a 100644 --- a/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java +++ b/sa-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java @@ -231,7 +231,7 @@ public class StpLogic { clearLastActivity(tokenValue); // 2. 尝试清除token-id键值对 (先从db中获取loginId值,如果根本查不到loginId,那么无需继续操作 ) - String loginId = SaTokenManager.getSaTokenDao().getValue(getKeyTokenValue(tokenValue)); + String loginId = getLoginIdNotHandle(tokenValue); if(loginId == null || NotLoginException.ABNORMAL_LIST.contains(loginId)) { return; } @@ -317,7 +317,7 @@ public class StpLogic { throw NotLoginException.newInstance(loginKey, NotLoginException.NOT_TOKEN); } // 查找此token对应loginId, 则抛出:无效token - String loginId = SaTokenManager.getSaTokenDao().getValue(getKeyTokenValue(tokenValue)); + String loginId = getLoginIdNotHandle(tokenValue); if(loginId == null) { throw NotLoginException.newInstance(loginKey, NotLoginException.INVALID_TOKEN); } @@ -377,7 +377,7 @@ public class StpLogic { return null; } // loginId为null或者在异常项里面,均视为未登录 - Object loginId = SaTokenManager.getSaTokenDao().getValue(getKeyTokenValue(tokenValue)); + Object loginId = getLoginIdNotHandle(tokenValue); if(loginId == null || NotLoginException.ABNORMAL_LIST.contains(loginId)) { return null; } @@ -427,16 +427,24 @@ public class StpLogic { * @return 登录id */ public Object getLoginIdByToken(String tokenValue) { - if(tokenValue != null) { - Object loginId = SaTokenManager.getSaTokenDao().getValue(getKeyTokenValue(tokenValue)); - if(loginId != null) { - return loginId; - } + if(tokenValue == null) { + return null; } - return null; + return getLoginIdNotHandle(tokenValue); } + /** + * 获取指定token对应的登录id (不做任何特殊处理) + * @param tokenValue token值 + * @return loginId + */ + public String getLoginIdNotHandle(String tokenValue) { + return SaTokenManager.getSaTokenDao().getValue(getKeyTokenValue(tokenValue)); + } + + + // =================== session相关 =================== /** diff --git a/sa-token-demo-jwt/.gitignore b/sa-token-demo-jwt/.gitignore new file mode 100644 index 00000000..99a6e767 --- /dev/null +++ b/sa-token-demo-jwt/.gitignore @@ -0,0 +1,12 @@ +target/ + +node_modules/ +bin/ +.settings/ +unpackage/ +.classpath +.project + +.idea/ + +.factorypath \ No newline at end of file diff --git a/sa-token-demo-jwt/pom.xml b/sa-token-demo-jwt/pom.xml new file mode 100644 index 00000000..38f28817 --- /dev/null +++ b/sa-token-demo-jwt/pom.xml @@ -0,0 +1,80 @@ + + 4.0.0 + cn.dev33 + sa-token-demo-jwt + 0.0.1-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-parent + 2.0.0.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-aop + + + + + cn.dev33 + sa-token-spring-boot-starter + 1.11.0 + + + + + io.jsonwebtoken + jjwt + 0.9.1 + + + + + + + + cn.dev33 + sa-token-dao-redis-jackson + 1.11.0 + + + + + org.apache.commons + commons-pool2 + + + + + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + + + + \ No newline at end of file diff --git a/sa-token-demo-jwt/src/main/java/com/pj/SaTokenJwtDemoApplication.java b/sa-token-demo-jwt/src/main/java/com/pj/SaTokenJwtDemoApplication.java new file mode 100644 index 00000000..10b42032 --- /dev/null +++ b/sa-token-demo-jwt/src/main/java/com/pj/SaTokenJwtDemoApplication.java @@ -0,0 +1,16 @@ +package com.pj; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +import cn.dev33.satoken.SaTokenManager; + +@SpringBootApplication +public class SaTokenJwtDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(SaTokenJwtDemoApplication.class, args); + System.out.println("\n启动成功:sa-token配置如下:" + SaTokenManager.getConfig()); + } + +} \ No newline at end of file diff --git a/sa-token-demo-jwt/src/main/java/com/pj/satoken/jwt/SaTokenJwtUtil.java b/sa-token-demo-jwt/src/main/java/com/pj/satoken/jwt/SaTokenJwtUtil.java new file mode 100644 index 00000000..7677824f --- /dev/null +++ b/sa-token-demo-jwt/src/main/java/com/pj/satoken/jwt/SaTokenJwtUtil.java @@ -0,0 +1,225 @@ +package com.pj.satoken.jwt; + +import java.util.Date; + +import javax.servlet.http.HttpServletRequest; + +import org.springframework.stereotype.Component; + +import cn.dev33.satoken.SaTokenManager; +import cn.dev33.satoken.config.SaTokenConfig; +import cn.dev33.satoken.dao.SaTokenDao; +import cn.dev33.satoken.exception.NotLoginException; +import cn.dev33.satoken.exception.SaTokenException; +import cn.dev33.satoken.session.SaSession; +import cn.dev33.satoken.stp.SaTokenInfo; +import cn.dev33.satoken.stp.StpLogic; +import cn.dev33.satoken.stp.StpUtil; +import cn.dev33.satoken.util.SaTokenConsts; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.JwtBuilder; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.MalformedJwtException; +import io.jsonwebtoken.SignatureAlgorithm; + +@Component +public class SaTokenJwtUtil { + + /** + * 秘钥 + */ + public static final String BASE64_SECURITY = "79e7c69681b8270162386e6daa53d1dd"; + + /** + * token有效期 (单位: 秒) + */ + public static final long TIMEOUT = 60 * 60 * 2; + + + public static final String LOGIN_ID_KEY = "loginId"; + + + /** + * 根据userId生成token + * @param loginId 账号id + * @param base64Security 秘钥 + * @return jwt-token + */ + public static String createToken(Object loginId) { + // 判断,不可使用默认秘钥 + if(BASE64_SECURITY.equals("79e7c69681b8270162386e6daa53d1d3")) { + throw new SaTokenException("请更换秘钥"); + } + // 在这里你可以使用官方提供的claim方法构建载荷,也可以使用setPayload自定义载荷,但是两者不可一起使用 + JwtBuilder builder = Jwts.builder() + .setHeaderParam("type", "JWT") + .claim(LOGIN_ID_KEY, loginId) + .setIssuedAt(new Date()) // 签发日期 + .setExpiration(new Date(System.currentTimeMillis() + 1000 * TIMEOUT)) // 有效截止日期 + .signWith(SignatureAlgorithm.HS256, BASE64_SECURITY.getBytes()); // 加密算法 + //生成JWT + return builder.compact(); + } + + /** + * 从一个jwt里面解析出Claims + * @param tokenValue token值 + * @param base64Security 秘钥 + * @return Claims对象 + */ + public static Claims getClaims(String tokenValue) { +// System.out.println(tokenValue); + Claims claims = Jwts.parser() + .setSigningKey(BASE64_SECURITY.getBytes()) + .parseClaimsJws(tokenValue).getBody(); + return claims; + } + + /** + * 从一个jwt里面解析loginId + * @param tokenValue token值 + * @param base64Security 秘钥 + * @return loginId + */ + public static String getLoginId(String tokenValue) { + try { + Object loginId = getClaims(tokenValue).get(LOGIN_ID_KEY); + if(loginId == null) { + return null; + } + return String.valueOf(loginId); + } catch (ExpiredJwtException e) { +// throw NotLoginException.newInstance(StpUtil.stpLogic.loginKey, NotLoginException.TOKEN_TIMEOUT); + return NotLoginException.TOKEN_TIMEOUT; + } catch (MalformedJwtException e) { + throw NotLoginException.newInstance(StpUtil.stpLogic.loginKey, NotLoginException.INVALID_TOKEN); + } catch (Exception e) { + throw new SaTokenException(e); + } + } + + + + static { + + // 修改默认实现 + StpUtil.stpLogic = new StpLogic("login") { + + // 重写 (随机生成一个tokenValue) + @Override + public String createTokenValue(Object loginId) { + return SaTokenJwtUtil.createToken(loginId); + } + + // 重写 (在当前会话上登录id ) + @Override + public void setLoginId(Object loginId, String device) { + // ------ 1、获取相应对象 + HttpServletRequest request = SaTokenManager.getSaTokenServlet().getRequest(); + SaTokenConfig config = getConfig(); + // ------ 2、生成一个token + String tokenValue = createTokenValue(loginId); + request.setAttribute(SaTokenConsts.JUST_CREATED_SAVE_KEY, tokenValue); // 将token保存到本次request里 + if(config.getIsReadCookie() == true){ // cookie注入 + SaTokenManager.getSaTokenCookie().addCookie(SaTokenManager.getSaTokenServlet().getResponse(), getTokenName(), tokenValue, "/", (int)config.getTimeout()); + } + } + + // 重写 (获取指定token对应的登录id) + @Override + public String getLoginIdNotHandle(String tokenValue) { + try { + return SaTokenJwtUtil.getLoginId(tokenValue); + } catch (Exception e) { + return null; + } + } + + // 重写 (当前会话注销登录) + @Override + public void logout() { + // 如果连token都没有,那么无需执行任何操作 + String tokenValue = getTokenValue(); + if(tokenValue == null) { + return; + } + // 如果打开了cookie模式,把cookie清除掉 + if(getConfig().getIsReadCookie() == true){ + SaTokenManager.getSaTokenCookie().delCookie(SaTokenManager.getSaTokenServlet().getRequest(), SaTokenManager.getSaTokenServlet().getResponse(), getTokenName()); + } + } + + // 重写 (获取指定key的session) + @Override + public SaSession getSessionBySessionId(String sessionId, boolean isCreate) { + throw new SaTokenException("jwt has not session"); + } + + // 重写 (获取当前登录者的token剩余有效时间 (单位: 秒)) + @Override + public long getTokenTimeout() { + // 如果没有token + String tokenValue = getTokenValue(); + if(tokenValue == null) { + return SaTokenDao.NOT_VALUE_EXPIRE; + } + // 开始取值 + Claims claims = null; + try { + claims = SaTokenJwtUtil.getClaims(tokenValue); + } catch (Exception e) { + return SaTokenDao.NOT_VALUE_EXPIRE; + } + if(claims == null) { + return SaTokenDao.NOT_VALUE_EXPIRE; + } + Date expiration = claims.getExpiration(); + if(expiration == null) { + return SaTokenDao.NOT_VALUE_EXPIRE; + } + return (expiration.getTime() - System.currentTimeMillis()) / 1000; + } + + // 重写 (返回当前token的登录设备) + @Override + public String getLoginDevice() { + return SaTokenConsts.DEFAULT_LOGIN_DEVICE; + } + + // 重写 (获取当前会话的token信息) + @Override + public SaTokenInfo getTokenInfo() { + SaTokenInfo info = new SaTokenInfo(); + info.tokenName = getTokenName(); + info.tokenValue = getTokenValue(); + info.isLogin = isLogin(); + info.loginId = getLoginIdDefaultNull(); + info.loginKey = getLoginKey(); + info.tokenTimeout = getTokenTimeout(); +// info.sessionTimeout = getSessionTimeout(); +// info.tokenSessionTimeout = getTokenSessionTimeout(); +// info.tokenActivityTimeout = getTokenActivityTimeout(); + info.loginDevice = getLoginDevice(); + return info; + } + + + }; + + + } + + + + + + + + + + + + + +} diff --git a/sa-token-demo-jwt/src/main/java/com/pj/test/GlobalException.java b/sa-token-demo-jwt/src/main/java/com/pj/test/GlobalException.java new file mode 100644 index 00000000..f128bcac --- /dev/null +++ b/sa-token-demo-jwt/src/main/java/com/pj/test/GlobalException.java @@ -0,0 +1,100 @@ +package com.pj.test; + +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import com.pj.util.AjaxJson; + +import cn.dev33.satoken.exception.NotLoginException; +import cn.dev33.satoken.exception.NotPermissionException; +import cn.dev33.satoken.exception.NotRoleException; + +/** + * 全局异常处理 + */ +@RestControllerAdvice // 可指定包前缀,比如:(basePackages = "com.pj.admin") +public class GlobalException { + + // 在每个控制器之前触发的操作 + @ModelAttribute + public void get(HttpServletRequest request) throws IOException { + + } + + + + + // 全局异常拦截(拦截项目中的所有异常) + @ExceptionHandler + public AjaxJson handlerException(Exception e, HttpServletRequest request, HttpServletResponse response) + throws Exception { + + // 打印堆栈,以供调试 + e.printStackTrace(); + + // 不同异常返回不同状态码 + AjaxJson aj = null; + if (e instanceof NotLoginException) { // 如果是未登录异常 + NotLoginException ee = (NotLoginException) e; + aj = AjaxJson.getNotLogin().setMsg(ee.getMessage()); + } else if(e instanceof NotRoleException) { // 如果是角色异常 + NotRoleException ee = (NotRoleException) e; + aj = AjaxJson.getNotJur("无此角色:" + ee.getRole()); + } else if(e instanceof NotPermissionException) { // 如果是权限异常 + NotPermissionException ee = (NotPermissionException) e; + aj = AjaxJson.getNotJur("无此权限:" + ee.getCode()); + } else { // 普通异常, 输出:500 + 异常信息 + aj = AjaxJson.getError(e.getMessage()); + } + + // 返回给前端 + return aj; + + // 输出到客户端 +// response.setContentType("application/json; charset=utf-8"); // http说明,我要返回JSON对象 +// response.getWriter().print(new ObjectMapper().writeValueAsString(aj)); + } + + + + // 全局异常拦截(拦截项目中的NotLoginException异常) +// @ExceptionHandler(NotLoginException.class) +// public AjaxJson handlerNotLoginException(NotLoginException nle, HttpServletRequest request, HttpServletResponse response) +// throws Exception { +// +// // 打印堆栈,以供调试 +// nle.printStackTrace(); +// +// // 判断场景值,定制化异常信息 +// String message = ""; +// if(nle.getType().equals(NotLoginException.NOT_TOKEN)) { +// message = "未提供token"; +// } +// else if(nle.getType().equals(NotLoginException.INVALID_TOKEN)) { +// message = "token无效"; +// } +// else if(nle.getType().equals(NotLoginException.TOKEN_TIMEOUT)) { +// message = "token已过期"; +// } +// else if(nle.getType().equals(NotLoginException.BE_REPLACED)) { +// message = "token已被顶下线"; +// } +// else if(nle.getType().equals(NotLoginException.KICK_OUT)) { +// message = "token已被踢下线"; +// } +// else { +// message = "当前会话未登录"; +// } +// +// // 返回给前端 +// return AjaxJson.getError(message); +// } + + +} diff --git a/sa-token-demo-jwt/src/main/java/com/pj/test/TestJwtController.java b/sa-token-demo-jwt/src/main/java/com/pj/test/TestJwtController.java new file mode 100644 index 00000000..dc60ba28 --- /dev/null +++ b/sa-token-demo-jwt/src/main/java/com/pj/test/TestJwtController.java @@ -0,0 +1,60 @@ +package com.pj.test; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.pj.util.AjaxJson; + +import cn.dev33.satoken.stp.SaTokenInfo; +import cn.dev33.satoken.stp.StpUtil; + +/** + * 测试专用Controller + * @author kong + * + */ +@RestController +@RequestMapping("/test/") +public class TestJwtController { + + + + // 测试登录接口, 浏览器访问: http://localhost:8081/test/login + @RequestMapping("login") + public AjaxJson login(@RequestParam(defaultValue="10001") String id) { + System.out.println("======================= 进入方法,测试登录接口 ========================= "); + System.out.println("当前会话的token:" + StpUtil.getTokenValue()); + System.out.println("当前是否登录:" + StpUtil.isLogin()); + System.out.println("当前登录账号:" + StpUtil.getLoginIdDefaultNull()); + + StpUtil.setLoginId(id); // 在当前会话登录此账号 + System.out.println("登录成功"); + System.out.println("当前是否登录:" + StpUtil.isLogin()); + System.out.println("当前登录账号:" + StpUtil.getLoginId()); +// System.out.println("当前登录账号并转为int:" + StpUtil.getLoginIdAsInt()); + System.out.println("当前登录设备:" + StpUtil.getLoginDevice()); +// System.out.println("当前token信息:" + StpUtil.getTokenInfo()); + + return AjaxJson.getSuccess(); + } + + // 打印当前token信息, 浏览器访问: http://localhost:8081/test/tokenInfo + @RequestMapping("tokenInfo") + public AjaxJson tokenInfo() { + System.out.println("======================= 进入方法,打印当前token信息 ========================= "); + SaTokenInfo tokenInfo = StpUtil.getTokenInfo(); + System.out.println(tokenInfo); + return AjaxJson.getSuccessData(tokenInfo); + } + + // 测试 浏览器访问: http://localhost:8081/test/test + @RequestMapping("test") + public AjaxJson test() { + StpUtil.getTokenSession().logout(); + StpUtil.logoutByLoginId(10001); + return AjaxJson.getSuccess(); + } + + +} diff --git a/sa-token-demo-jwt/src/main/java/com/pj/util/AjaxJson.java b/sa-token-demo-jwt/src/main/java/com/pj/util/AjaxJson.java new file mode 100644 index 00000000..768d0578 --- /dev/null +++ b/sa-token-demo-jwt/src/main/java/com/pj/util/AjaxJson.java @@ -0,0 +1,162 @@ +package com.pj.util; + +import java.io.Serializable; +import java.util.List; + + +/** + * ajax请求返回Json格式数据的封装 + */ +public class AjaxJson implements Serializable{ + + private static final long serialVersionUID = 1L; // 序列化版本号 + + public static final int CODE_SUCCESS = 200; // 成功状态码 + public static final int CODE_ERROR = 500; // 错误状态码 + public static final int CODE_WARNING = 501; // 警告状态码 + public static final int CODE_NOT_JUR = 403; // 无权限状态码 + public static final int CODE_NOT_LOGIN = 401; // 未登录状态码 + public static final int CODE_INVALID_REQUEST = 400; // 无效请求状态码 + + public int code; // 状态码 + public String msg; // 描述信息 + public Object data; // 携带对象 + public Long dataCount; // 数据总数,用于分页 + + /** + * 返回code + * @return + */ + public int getCode() { + return this.code; + } + + /** + * 给msg赋值,连缀风格 + */ + public AjaxJson setMsg(String msg) { + this.msg = msg; + return this; + } + public String getMsg() { + return this.msg; + } + + /** + * 给data赋值,连缀风格 + */ + public AjaxJson setData(Object data) { + this.data = data; + return this; + } + + /** + * 将data还原为指定类型并返回 + */ + @SuppressWarnings("unchecked") + public T getData(Class cs) { + return (T) data; + } + + // ============================ 构建 ================================== + + public AjaxJson(int code, String msg, Object data, Long dataCount) { + this.code = code; + this.msg = msg; + this.data = data; + this.dataCount = dataCount; + } + + // 返回成功 + public static AjaxJson getSuccess() { + return new AjaxJson(CODE_SUCCESS, "ok", null, null); + } + public static AjaxJson getSuccess(String msg) { + return new AjaxJson(CODE_SUCCESS, msg, null, null); + } + public static AjaxJson getSuccess(String msg, Object data) { + return new AjaxJson(CODE_SUCCESS, msg, data, null); + } + public static AjaxJson getSuccessData(Object data) { + return new AjaxJson(CODE_SUCCESS, "ok", data, null); + } + public static AjaxJson getSuccessArray(Object... data) { + return new AjaxJson(CODE_SUCCESS, "ok", data, null); + } + + // 返回失败 + public static AjaxJson getError() { + return new AjaxJson(CODE_ERROR, "error", null, null); + } + public static AjaxJson getError(String msg) { + return new AjaxJson(CODE_ERROR, msg, null, null); + } + + // 返回警告 + public static AjaxJson getWarning() { + return new AjaxJson(CODE_ERROR, "warning", null, null); + } + public static AjaxJson getWarning(String msg) { + return new AjaxJson(CODE_WARNING, msg, null, null); + } + + // 返回未登录 + public static AjaxJson getNotLogin() { + return new AjaxJson(CODE_NOT_LOGIN, "未登录,请登录后再次访问", null, null); + } + + // 返回没有权限的 + public static AjaxJson getNotJur(String msg) { + return new AjaxJson(CODE_NOT_JUR, msg, null, null); + } + + // 返回一个自定义状态码的 + public static AjaxJson get(int code, String msg){ + return new AjaxJson(code, msg, null, null); + } + + // 返回分页和数据的 + public static AjaxJson getPageData(Long dataCount, Object data){ + return new AjaxJson(CODE_SUCCESS, "ok", data, dataCount); + } + + // 返回,根据受影响行数的(大于0=ok,小于0=error) + public static AjaxJson getByLine(int line){ + if(line > 0){ + return getSuccess("ok", line); + } + return getError("error").setData(line); + } + + // 返回,根据布尔值来确定最终结果的 (true=ok,false=error) + public static AjaxJson getByBoolean(boolean b){ + return b ? getSuccess("ok") : getError("error"); + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @SuppressWarnings("rawtypes") + @Override + public String toString() { + String data_string = null; + if(data == null){ + + } else if(data instanceof List){ + data_string = "List(length=" + ((List)data).size() + ")"; + } else { + data_string = data.toString(); + } + return "{" + + "\"code\": " + this.getCode() + + ", \"msg\": \"" + this.getMsg() + "\"" + + ", \"data\": " + data_string + + ", \"dataCount\": " + dataCount + + "}"; + } + + + + + +} diff --git a/sa-token-demo-jwt/src/main/resources/application.yml b/sa-token-demo-jwt/src/main/resources/application.yml new file mode 100644 index 00000000..0ee1952f --- /dev/null +++ b/sa-token-demo-jwt/src/main/resources/application.yml @@ -0,0 +1,45 @@ +# 端口 +server: + port: 8081 + +spring: + # sa-token配置 + sa-token: + # token名称 (同时也是cookie名称) + token-name: satoken + # token有效期,单位s 默认30天, -1代表永不过期 + timeout: 2592000 + # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒 + activity-timeout: -1 + # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) + allow-concurrent-login: true + # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) + is-share: true + # token风格 + token-style: uuid + + + # redis配置 + redis: + # Redis数据库索引(默认为0) + database: 0 + # Redis服务器地址 + host: 127.0.0.1 + # Redis服务器连接端口 + port: 6379 + # Redis服务器连接密码(默认为空) + password: + # 连接超时时间(毫秒) + timeout: 10000ms + lettuce: + pool: + # 连接池最大连接数 + max-active: 200 + # 连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms + # 连接池中的最大空闲连接 + max-idle: 10 + # 连接池中的最小空闲连接 + min-idle: 0 + + \ No newline at end of file diff --git a/sa-token-doc/doc/index.html b/sa-token-doc/doc/index.html index b6dfccfa..9aaf78d6 100644 --- a/sa-token-doc/doc/index.html +++ b/sa-token-doc/doc/index.html @@ -2,7 +2,7 @@ - sa-token + sa-token 官方文档 diff --git a/sa-token-doc/index.html b/sa-token-doc/index.html index 5b441bdc..007a064a 100644 --- a/sa-token-doc/index.html +++ b/sa-token-doc/index.html @@ -2,7 +2,7 @@ - sa-token 官方文档 + sa-token diff --git a/sa-token-spring-aop/src/main/java/cn/dev33/satoken/aop/SaCheckAspect.java b/sa-token-spring-aop/src/main/java/cn/dev33/satoken/aop/SaCheckAspect.java index c68894e1..84a71c3d 100644 --- a/sa-token-spring-aop/src/main/java/cn/dev33/satoken/aop/SaCheckAspect.java +++ b/sa-token-spring-aop/src/main/java/cn/dev33/satoken/aop/SaCheckAspect.java @@ -19,16 +19,18 @@ import cn.dev33.satoken.stp.StpUtil; public class SaCheckAspect { /** - * 底层的 StpLogic 对象 - */ - public StpLogic stpLogic = null; - - /** - * 创建,并指定一个默认的 StpLogic + * 创建 */ public SaCheckAspect() { - this.stpLogic = StpUtil.stpLogic; } + + /** + * 获取本切面使用的StpLogic + */ + public StpLogic getStpLogic() { + return StpUtil.stpLogic; + } + /** * 定义AOP签名 (切入所有使用sa-token鉴权注解的方法) @@ -54,7 +56,7 @@ public class SaCheckAspect { public Object around(ProceedingJoinPoint joinPoint) throws Throwable { // 注解鉴权 MethodSignature signature = (MethodSignature) joinPoint.getSignature(); - stpLogic.checkMethodAnnotation(signature.getMethod()); + getStpLogic().checkMethodAnnotation(signature.getMethod()); try { // 执行原有逻辑 Object obj = joinPoint.proceed();