完善源码注释

This commit is contained in:
shengzhang 2021-01-30 18:06:14 +08:00
parent 03e38c549a
commit 26ee628b33
35 changed files with 717 additions and 649 deletions

View File

@ -3,6 +3,7 @@ package cn.dev33.satoken.action;
import java.util.UUID; import java.util.UUID;
import cn.dev33.satoken.SaTokenManager; import cn.dev33.satoken.SaTokenManager;
import cn.dev33.satoken.util.SaTokenConsts;
import cn.dev33.satoken.util.SaTokenInsideUtil; import cn.dev33.satoken.util.SaTokenInsideUtil;
/** /**
@ -21,30 +22,30 @@ public class SaTokenActionDefaultImpl implements SaTokenAction {
// 根据配置的tokenStyle生成不同风格的token // 根据配置的tokenStyle生成不同风格的token
String tokenStyle = SaTokenManager.getConfig().getTokenStyle(); String tokenStyle = SaTokenManager.getConfig().getTokenStyle();
// uuid // uuid
if("uuid".equals(tokenStyle)) { if(SaTokenConsts.TOKEN_STYLE_UUID.equals(tokenStyle)) {
return UUID.randomUUID().toString(); return UUID.randomUUID().toString();
} }
// 简单uuid (不带下划线) // 简单uuid (不带下划线)
if("simple-uuid".equals(tokenStyle)) { if(SaTokenConsts.TOKEN_STYLE_SIMPLE_UUID.equals(tokenStyle)) {
return UUID.randomUUID().toString().replaceAll("-", ""); return UUID.randomUUID().toString().replaceAll("-", "");
} }
// 32位随机字符串 // 32位随机字符串
if("random-32".equals(tokenStyle)) { if(SaTokenConsts.TOKEN_STYLE_RANDOM_32.equals(tokenStyle)) {
return SaTokenInsideUtil.getRandomString(32); return SaTokenInsideUtil.getRandomString(32);
} }
// 64位随机字符串 // 64位随机字符串
if("random-64".equals(tokenStyle)) { if(SaTokenConsts.TOKEN_STYLE_RANDOM_64.equals(tokenStyle)) {
return SaTokenInsideUtil.getRandomString(64); return SaTokenInsideUtil.getRandomString(64);
} }
// 128位随机字符串 // 128位随机字符串
if("random-128".equals(tokenStyle)) { if(SaTokenConsts.TOKEN_STYLE_RANDOM_128.equals(tokenStyle)) {
return SaTokenInsideUtil.getRandomString(128); return SaTokenInsideUtil.getRandomString(128);
} }
// tik风格 (2_14_16) // tik风格 (2_14_16)
if("tik".equals(tokenStyle)) { if(SaTokenConsts.TOKEN_STYLE_RANDOM_TIK.equals(tokenStyle)) {
return SaTokenInsideUtil.getRandomString(2) + "_" + SaTokenInsideUtil.getRandomString(14) + "_" + SaTokenInsideUtil.getRandomString(16) + "__"; return SaTokenInsideUtil.getRandomString(2) + "_" + SaTokenInsideUtil.getRandomString(14) + "_" + SaTokenInsideUtil.getRandomString(16) + "__";
} }
// 默认还是uuid // 默认还是uuid
return UUID.randomUUID().toString(); return UUID.randomUUID().toString();
} }

View File

@ -1,220 +1,226 @@
package cn.dev33.satoken.config; package cn.dev33.satoken.config;
/** /**
* sa-token 配置类 Model * sa-token 配置类 Model
* <p> 你可以通过ymlpropertiesjava代码等形式配置本类参数具体请查阅官方文档 * <p>
* 你可以通过ymlpropertiesjava代码等形式配置本类参数具体请查阅官方文档: http://sa-token.dev33.cn/
*
* @author kong * @author kong
* *
*/ */
public class SaTokenConfig { public class SaTokenConfig {
/** token名称 (同时也是cookie名称) */ /** token名称 (同时也是cookie名称) */
private String tokenName = "satoken"; private String tokenName = "satoken";
/** token的长久有效期(单位:秒) 默认30天, -1代表永久 */ /** token的长久有效期(单位:秒) 默认30天, -1代表永久 */
private long timeout = 30 * 24 * 60 * 60; private long timeout = 30 * 24 * 60 * 60;
/** token临时有效期 [指定时间内无操作就视为token过期] (单位/秒), 默认-1 代表不限制 (例如可以设置为1800代表30分钟内无操作就过期) */ /**
private long activityTimeout = -1; * token临时有效期 [指定时间内无操作就视为token过期] (单位: ), 默认-1 代表不限制
* (例如可以设置为1800代表30分钟内无操作就过期)
/** 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) */ */
private Boolean allowConcurrentLogin = true; private long activityTimeout = -1;
/** 在多人登录同一账号时是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) */ /** 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) */
private Boolean isShare = true; private Boolean allowConcurrentLogin = true;
/** 在多人登录同一账号时是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) */
private Boolean isShare = true;
/** 是否尝试从请求体里读取token */ /** 是否尝试从请求体里读取token */
private Boolean isReadBody = true; private Boolean isReadBody = true;
/** 是否尝试从header里读取token */ /** 是否尝试从header里读取token */
private Boolean isReadHead = true; private Boolean isReadHead = true;
/** 是否尝试从cookie里读取token */ /** 是否尝试从cookie里读取token */
private Boolean isReadCookie = true; private Boolean isReadCookie = true;
/** token风格(默认可取值uuid、simple-uuid、random-32、random-64、random-128、tik) */ /** token风格(默认可取值uuid、simple-uuid、random-32、random-64、random-128、tik) */
private String tokenStyle = "uuid"; private String tokenStyle = "uuid";
/** 默认dao层实现类中每次清理过期数据间隔的时间 (单位: 秒) 默认值30秒设置为-1代表不启动定时清理 */ /** 默认dao层实现类中每次清理过期数据间隔的时间 (单位: 秒) 默认值30秒设置为-1代表不启动定时清理 */
private int dataRefreshPeriod = 30; private int dataRefreshPeriod = 30;
/** 获取[token专属session]时是否必须登录 (如果配置为true会在每次获取[token-session]时校验是否登录) */ /** 获取[token专属session]时是否必须登录 (如果配置为true会在每次获取[token-session]时校验是否登录) */
private Boolean tokenSessionCheckLogin = true; private Boolean tokenSessionCheckLogin = true;
/** 是否在初始化配置时打印版本字符画 */ /** 是否在初始化配置时打印版本字符画 */
private Boolean isV = true; private Boolean isV = true;
/** /**
* @return tokenName * @return token名称 (同时也是cookie名称)
*/ */
public String getTokenName() { public String getTokenName() {
return tokenName; return tokenName;
} }
/** /**
* @param tokenName 要设置的 tokenName * @param tokenName token名称 (同时也是cookie名称)
*/ */
public void setTokenName(String tokenName) { public void setTokenName(String tokenName) {
this.tokenName = tokenName; this.tokenName = tokenName;
} }
/** /**
* @return timeout * @return token的长久有效期(单位:) 默认30天, -1代表永久
*/ */
public long getTimeout() { public long getTimeout() {
return timeout; return timeout;
} }
/** /**
* @param timeout 要设置的 timeout * @param timeout token的长久有效期(单位:) 默认30天, -1代表永久
*/ */
public void setTimeout(long timeout) { public void setTimeout(long timeout) {
this.timeout = timeout; this.timeout = timeout;
} }
/** /**
* @return activityTimeout * @return token临时有效期 [指定时间内无操作就视为token过期] (单位: ), 默认-1 代表不限制
* (例如可以设置为1800代表30分钟内无操作就过期)
*/ */
public long getActivityTimeout() { public long getActivityTimeout() {
return activityTimeout; return activityTimeout;
} }
/** /**
* @param activityTimeout 要设置的 activityTimeout * @param activityTimeout token临时有效期 [指定时间内无操作就视为token过期] (单位: ), 默认-1 代表不限制
* (例如可以设置为1800代表30分钟内无操作就过期)
*/ */
public void setActivityTimeout(long activityTimeout) { public void setActivityTimeout(long activityTimeout) {
this.activityTimeout = activityTimeout; this.activityTimeout = activityTimeout;
} }
/** /**
* @return allowConcurrentLogin * @return 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
*/ */
public Boolean getAllowConcurrentLogin() { public Boolean getAllowConcurrentLogin() {
return allowConcurrentLogin; return allowConcurrentLogin;
} }
/** /**
* @param allowConcurrentLogin 要设置的 allowConcurrentLogin * @param allowConcurrentLogin 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
*/ */
public void setAllowConcurrentLogin(Boolean allowConcurrentLogin) { public void setAllowConcurrentLogin(Boolean allowConcurrentLogin) {
this.allowConcurrentLogin = allowConcurrentLogin; this.allowConcurrentLogin = allowConcurrentLogin;
} }
/** /**
* @return isShare * @return 在多人登录同一账号时是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
*/ */
public Boolean getIsShare() { public Boolean getIsShare() {
return isShare; return isShare;
} }
/** /**
* @param isShare 要设置的 isShare * @param 在多人登录同一账号时是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
*/ */
public void setIsShare(Boolean isShare) { public void setIsShare(Boolean isShare) {
this.isShare = isShare; this.isShare = isShare;
} }
/** /**
* @return isReadBody * @return 是否尝试从请求体里读取token
*/ */
public Boolean getIsReadBody() { public Boolean getIsReadBody() {
return isReadBody; return isReadBody;
} }
/** /**
* @param isReadBody 要设置的 isReadBody * @param isReadBody 是否尝试从请求体里读取token
*/ */
public void setIsReadBody(Boolean isReadBody) { public void setIsReadBody(Boolean isReadBody) {
this.isReadBody = isReadBody; this.isReadBody = isReadBody;
} }
/** /**
* @return isReadHead * @return 是否尝试从header里读取token
*/ */
public Boolean getIsReadHead() { public Boolean getIsReadHead() {
return isReadHead; return isReadHead;
} }
/** /**
* @param isReadHead 要设置的 isReadHead * @param 是否尝试从header里读取token
*/ */
public void setIsReadHead(Boolean isReadHead) { public void setIsReadHead(Boolean isReadHead) {
this.isReadHead = isReadHead; this.isReadHead = isReadHead;
} }
/** /**
* @return isReadCookie * @return 是否尝试从cookie里读取token
*/ */
public Boolean getIsReadCookie() { public Boolean getIsReadCookie() {
return isReadCookie; return isReadCookie;
} }
/** /**
* @param isReadCookie 要设置的 isReadCookie * @param 是否尝试从cookie里读取token
*/ */
public void setIsReadCookie(Boolean isReadCookie) { public void setIsReadCookie(Boolean isReadCookie) {
this.isReadCookie = isReadCookie; this.isReadCookie = isReadCookie;
} }
/** /**
* @return tokenStyle * @return token风格(默认可取值uuidsimple-uuidrandom-32random-64random-128tik)
*/ */
public String getTokenStyle() { public String getTokenStyle() {
return tokenStyle; return tokenStyle;
} }
/** /**
* @param tokenStyle 要设置的 tokenStyle * @param token风格(默认可取值uuidsimple-uuidrandom-32random-64random-128tik)
*/ */
public void setTokenStyle(String tokenStyle) { public void setTokenStyle(String tokenStyle) {
this.tokenStyle = tokenStyle; this.tokenStyle = tokenStyle;
} }
/** /**
* @return dataRefreshPeriod * @return 默认dao层实现类中每次清理过期数据间隔的时间 (单位: ) 默认值30秒设置为-1代表不启动定时清理
*/ */
public int getDataRefreshPeriod() { public int getDataRefreshPeriod() {
return dataRefreshPeriod; return dataRefreshPeriod;
} }
/** /**
* @param dataRefreshPeriod 要设置的 dataRefreshPeriod * @param dataRefreshPeriod 默认dao层实现类中每次清理过期数据间隔的时间 (单位: )
* 默认值30秒设置为-1代表不启动定时清理
*/ */
public void setDataRefreshPeriod(int dataRefreshPeriod) { public void setDataRefreshPeriod(int dataRefreshPeriod) {
this.dataRefreshPeriod = dataRefreshPeriod; this.dataRefreshPeriod = dataRefreshPeriod;
} }
/** /**
* @return tokenSessionCheckLogin * @return 获取[token专属session]时是否必须登录 (如果配置为true会在每次获取[token-session]时校验是否登录)
*/ */
public Boolean getTokenSessionCheckLogin() { public Boolean getTokenSessionCheckLogin() {
return tokenSessionCheckLogin; return tokenSessionCheckLogin;
} }
/** /**
* @param tokenSessionCheckLogin 要设置的 tokenSessionCheckLogin * @param tokenSessionCheckLogin 获取[token专属session]时是否必须登录
* (如果配置为true会在每次获取[token-session]时校验是否登录)
*/ */
public void setTokenSessionCheckLogin(Boolean tokenSessionCheckLogin) { public void setTokenSessionCheckLogin(Boolean tokenSessionCheckLogin) {
this.tokenSessionCheckLogin = tokenSessionCheckLogin; this.tokenSessionCheckLogin = tokenSessionCheckLogin;
} }
/** /**
* @return isV * @return 是否在初始化配置时打印版本字符画
*/ */
public Boolean getIsV() { public Boolean getIsV() {
return isV; return isV;
} }
/** /**
* @param isV 要设置的 isV * @param isV 是否在初始化配置时打印版本字符画
*/ */
public void setIsV(Boolean isV) { public void setIsV(Boolean isV) {
this.isV = isV; this.isV = isV;
} }
@Override @Override
public String toString() { public String toString() {
return "SaTokenConfig [tokenName=" + tokenName + ", timeout=" + timeout + ", activityTimeout=" + activityTimeout return "SaTokenConfig [tokenName=" + tokenName + ", timeout=" + timeout + ", activityTimeout=" + activityTimeout
@ -224,22 +230,4 @@ public class SaTokenConfig {
+ tokenSessionCheckLogin + ", isV=" + isV + "]"; + tokenSessionCheckLogin + ", isV=" + isV + "]";
} }
} }

View File

@ -8,44 +8,46 @@ import java.util.Map;
import java.util.Properties; import java.util.Properties;
/** /**
* sa-token配置文件创建工厂类 * sa-token配置文件的构建工厂类
* <p>
* 只有在非IOC环境下才会用到此类
*
* @author kong * @author kong
* *
*/ */
public class SaTokenConfigFactory { public class SaTokenConfigFactory {
/** /**
* 默认配置文件地址 * 配置文件地址
*/ */
public static String configPath = "sa-token.properties"; public static String configPath = "sa-token.properties";
/** /**
* 根据指定路径获取配置信息 * 根据configPath路径获取配置信息
* @return 一个SaTokenConfig对象 *
* @return 一个SaTokenConfig对象
*/ */
public static SaTokenConfig createConfig() { public static SaTokenConfig createConfig() {
Map<String, String> map = readPropToMap(configPath); Map<String, String> map = readPropToMap(configPath);
if(map == null){ if (map == null) {
// throw new RuntimeException("找不到配置文件:" + configPath, null); // throw new RuntimeException("找不到配置文件:" + configPath, null);
} }
return (SaTokenConfig)initPropByMap(map, new SaTokenConfig()); return (SaTokenConfig) initPropByMap(map, new SaTokenConfig());
} }
/** /**
* 将指定路径的properties配置文件读取到Map中 * 工具方法: 将指定路径的properties配置文件读取到Map中
*
* @param propertiesPath 配置文件地址 * @param propertiesPath 配置文件地址
* @return 一个Map * @return 一个Map
*/ */
private static Map<String, String> readPropToMap(String propertiesPath){ private static Map<String, String> readPropToMap(String propertiesPath) {
Map<String, String> map = new HashMap<String, String>(); Map<String, String> map = new HashMap<String, String>(16);
try { try {
InputStream is = SaTokenConfigFactory.class.getClassLoader().getResourceAsStream(propertiesPath); InputStream is = SaTokenConfigFactory.class.getClassLoader().getResourceAsStream(propertiesPath);
if(is == null){ if (is == null) {
return null; return null;
} }
Properties prop = new Properties(); Properties prop = new Properties();
prop.load(is); prop.load(is);
for (String key : prop.stringPropertyNames()) { for (String key : prop.stringPropertyNames()) {
@ -55,38 +57,41 @@ public class SaTokenConfigFactory {
throw new RuntimeException("配置文件(" + propertiesPath + ")加载失败", e); throw new RuntimeException("配置文件(" + propertiesPath + ")加载失败", e);
} }
return map; return map;
} }
/**
/** * 工具方法: Map 的值映射到一个 Model
* Map 的值映射到 Model *
* @param map 属性集合 * @param map 属性集合
* @param obj 对象或类型 * @param obj 对象, 或类型
* @return 返回实例化后的对象 * @return 返回实例化后的对象
*/ */
private static Object initPropByMap(Map<String, String> map, Object obj){ private static Object initPropByMap(Map<String, String> map, Object obj) {
if(map == null){ if (map == null) {
map = new HashMap<String, String>(); map = new HashMap<String, String>(16);
} }
// 1取出类型 // 1取出类型
Class<?> cs = null; Class<?> cs = null;
if(obj instanceof Class){ // 如果是一个类型则将obj=null以便完成静态属性反射赋值 if (obj instanceof Class) {
cs = (Class<?>)obj; // 如果是一个类型则将obj=null以便完成静态属性反射赋值
obj = null; cs = (Class<?>) obj;
}else{ // 如果是一个对象则取出其类型 obj = null;
cs = obj.getClass(); } else {
} // 如果是一个对象则取出其类型
cs = obj.getClass();
// 2遍历类型属性反射赋值 }
for (Field field : cs.getDeclaredFields()) {
// 2遍历类型属性反射赋值
for (Field field : cs.getDeclaredFields()) {
String value = map.get(field.getName()); String value = map.get(field.getName());
if (value == null) { if (value == null) {
continue; // 如果为空代表没有配置此项 // 如果为空代表没有配置此项
continue;
} }
try { try {
Object valueConvert = getObjectByClass(value, field.getType()); // 转换值类型 Object valueConvert = getObjectByClass(value, field.getType());
field.setAccessible(true); field.setAccessible(true);
field.set(obj, valueConvert); field.set(obj, valueConvert);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
@ -95,41 +100,39 @@ public class SaTokenConfigFactory {
throw new RuntimeException("属性赋值出错:" + field.getName(), e); throw new RuntimeException("属性赋值出错:" + field.getName(), e);
} }
} }
return obj; return obj;
}
/**
* 将字符串转化为指定数据类型
* @param str
* @param cs 要转换的类型
* @return 转化好的结果
*/
@SuppressWarnings("unchecked")
private static <T>T getObjectByClass(String str, Class<T> cs){
Object value = null;
if(str == null){
value = null;
}else if (cs.equals(String.class)) {
value = str;
} else if (cs.equals(int.class)||cs.equals(Integer.class)) {
value = new Integer(str);
} else if (cs.equals(long.class)||cs.equals(Long.class)) {
value = new Long(str);
} else if (cs.equals(short.class)||cs.equals(Short.class)) {
value = new Short(str);
} else if (cs.equals(float.class)||cs.equals(Float.class)) {
value = new Float(str);
} else if (cs.equals(double.class)||cs.equals(Double.class)) {
value = new Double(str);
} else if (cs.equals(boolean.class)||cs.equals(Boolean.class)) {
value = new Boolean(str);
}else{
throw new RuntimeException("未能将值:" + str + ",转换类型为:" + cs, null);
}
return (T)value;
} }
/**
* 工具方法: 将字符串转化为指定数据类型
*
* @param str
* @param cs 要转换的类型
* @return 转化好的结果
*/
@SuppressWarnings("unchecked")
private static <T> T getObjectByClass(String str, Class<T> cs) {
Object value = null;
if (str == null) {
value = null;
} else if (cs.equals(String.class)) {
value = str;
} else if (cs.equals(int.class) || cs.equals(Integer.class)) {
value = new Integer(str);
} else if (cs.equals(long.class) || cs.equals(Long.class)) {
value = new Long(str);
} else if (cs.equals(short.class) || cs.equals(Short.class)) {
value = new Short(str);
} else if (cs.equals(float.class) || cs.equals(Float.class)) {
value = new Float(str);
} else if (cs.equals(double.class) || cs.equals(Double.class)) {
value = new Double(str);
} else if (cs.equals(boolean.class) || cs.equals(Boolean.class)) {
value = new Boolean(str);
} else {
throw new RuntimeException("未能将值:" + str + ",转换类型为:" + cs, null);
}
return (T) value;
}
} }

View File

@ -5,7 +5,8 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
/** /**
* sa-token 对cookie的相关操作 接口类 * sa-token 对cookie的相关操作 接口类
*
* @author kong * @author kong
* *
*/ */
@ -13,36 +14,40 @@ public interface SaTokenCookie {
/** /**
* 在request对象中获取指定Cookie * 在request对象中获取指定Cookie
* @param request request对象 *
* @param cookieName Cookie名称 * @param request request对象
* @param cookieName Cookie名称
* @return 查找到的Cookie对象 * @return 查找到的Cookie对象
*/ */
public Cookie getCookie(HttpServletRequest request, String cookieName); public Cookie getCookie(HttpServletRequest request, String cookieName);
/** /**
* 添加Cookie * 添加Cookie
* @param response response对象 *
* @param name Cookie名称 * @param response response对象
* @param value Cookie值 * @param name Cookie名称
* @param path Cookie路径 * @param value Cookie值
* @param path Cookie路径
* @param timeout 过期时间 * @param timeout 过期时间
*/ */
public void addCookie(HttpServletResponse response, String name, String value, String path, int timeout); public void addCookie(HttpServletResponse response, String name, String value, String path, int timeout);
/** /**
* 删除Cookie * 删除Cookie
* @param request request对象 *
* @param response response对象 * @param request request对象
* @param response response对象
* @param name Cookie名称 * @param name Cookie名称
*/ */
public void delCookie(HttpServletRequest request, HttpServletResponse response, String name); public void delCookie(HttpServletRequest request, HttpServletResponse response, String name);
/** /**
* 修改Cookie的value值 * 修改Cookie的value值
* @param request request对象 *
* @param request request对象
* @param response response对象 * @param response response对象
* @param name Cookie名称 * @param name Cookie名称
* @param value Cookie值 * @param value Cookie值
*/ */
public void updateCookie(HttpServletRequest request, HttpServletResponse response, String name, String value); public void updateCookie(HttpServletRequest request, HttpServletResponse response, String name, String value);

View File

@ -5,14 +5,15 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
/** /**
* sa-token 对cookie的相关操作 接口实现类 * sa-token 对cookie的相关操作 接口实现类
*
* @author kong * @author kong
* *
*/ */
public class SaTokenCookieDefaultImpl implements SaTokenCookie { public class SaTokenCookieDefaultImpl implements SaTokenCookie {
/** /**
* 获取指定cookie * 获取指定cookie
*/ */
@Override @Override
public Cookie getCookie(HttpServletRequest request, String cookieName) { public Cookie getCookie(HttpServletRequest request, String cookieName) {
@ -20,7 +21,7 @@ public class SaTokenCookieDefaultImpl implements SaTokenCookie {
} }
/** /**
* 添加cookie * 添加cookie
*/ */
@Override @Override
public void addCookie(HttpServletResponse response, String name, String value, String path, int timeout) { public void addCookie(HttpServletResponse response, String name, String value, String path, int timeout) {
@ -28,7 +29,7 @@ public class SaTokenCookieDefaultImpl implements SaTokenCookie {
} }
/** /**
* 删除cookie * 删除cookie
*/ */
@Override @Override
public void delCookie(HttpServletRequest request, HttpServletResponse response, String name) { public void delCookie(HttpServletRequest request, HttpServletResponse response, String name) {
@ -36,7 +37,7 @@ public class SaTokenCookieDefaultImpl implements SaTokenCookie {
} }
/** /**
* 修改cookie的value值 * 修改cookie的value值
*/ */
@Override @Override
public void updateCookie(HttpServletRequest request, HttpServletResponse response, String name, String value) { public void updateCookie(HttpServletRequest request, HttpServletResponse response, String name, String value) {

View File

@ -5,15 +5,17 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
/** /**
* Cookie操作工具类 * Cookie操作工具类
* @author kong *
* @author kong
*/ */
public class SaTokenCookieUtil { public class SaTokenCookieUtil {
/** /**
* 在request对象中获取指定Cookie * 在request对象中获取指定Cookie
* @param request request对象 *
* @param cookieName Cookie名称 * @param request request对象
* @param cookieName Cookie名称
* @return 查找到的Cookie对象 * @return 查找到的Cookie对象
*/ */
public static Cookie getCookie(HttpServletRequest request, String cookieName) { public static Cookie getCookie(HttpServletRequest request, String cookieName) {
@ -30,11 +32,12 @@ public class SaTokenCookieUtil {
/** /**
* 添加cookie * 添加cookie
*
* @param response response * @param response response
* @param name Cookie名称 * @param name Cookie名称
* @param value Cookie值 * @param value Cookie值
* @param path Cookie写入路径 * @param path Cookie写入路径
* @param timeout Cookie有效期 () * @param timeout Cookie有效期 ()
*/ */
public static void addCookie(HttpServletResponse response, String name, String value, String path, int timeout) { public static void addCookie(HttpServletResponse response, String name, String value, String path, int timeout) {
Cookie cookie = new Cookie(name, value); Cookie cookie = new Cookie(name, value);
@ -48,9 +51,10 @@ public class SaTokenCookieUtil {
/** /**
* 删除Cookie * 删除Cookie
*
* @param request request对象 * @param request request对象
* @param response response对象 * @param response response对象
* @param name Cookie名称 * @param name Cookie名称
*/ */
public static void delCookie(HttpServletRequest request, HttpServletResponse response, String name) { public static void delCookie(HttpServletRequest request, HttpServletResponse response, String name) {
Cookie[] cookies = request.getCookies(); Cookie[] cookies = request.getCookies();
@ -66,10 +70,11 @@ public class SaTokenCookieUtil {
/** /**
* 修改cookie的value值 * 修改cookie的value值
* @param request request对象 *
* @param response response对象 * @param request request对象
* @param name Cookie名称 * @param response response对象
* @param value Cookie值 * @param name Cookie名称
* @param value Cookie值
*/ */
public static void updateCookie(HttpServletRequest request, HttpServletResponse response, String name, public static void updateCookie(HttpServletRequest request, HttpServletResponse response, String name,
String value) { String value) {

View File

@ -22,7 +22,7 @@ public class SaTokenDaoDefaultImpl implements SaTokenDao {
/** /**
* 所有数据集合 * 数据集合
*/ */
public Map<String, Object> dataMap = new ConcurrentHashMap<String, Object>(); public Map<String, Object> dataMap = new ConcurrentHashMap<String, Object>();

View File

@ -10,7 +10,7 @@ import java.util.List;
public class NotLoginException extends RuntimeException { public class NotLoginException extends RuntimeException {
/** /**
* * 序列化版本号
*/ */
private static final long serialVersionUID = 6806129545290130142L; private static final long serialVersionUID = 6806129545290130142L;
@ -56,6 +56,7 @@ public class NotLoginException extends RuntimeException {
* 异常类型 * 异常类型
*/ */
private String type; private String type;
/** /**
* 获取异常类型 * 获取异常类型
* @return 异常类型 * @return 异常类型
@ -69,6 +70,7 @@ public class NotLoginException extends RuntimeException {
* loginKey * loginKey
*/ */
private String loginKey; private String loginKey;
/** /**
* 获得loginKey * 获得loginKey
* @return loginKey * @return loginKey
@ -78,8 +80,6 @@ public class NotLoginException extends RuntimeException {
} }
/** /**
* 构造方法创建一个 * 构造方法创建一个
* @param message 异常消息 * @param message 异常消息
@ -87,7 +87,6 @@ public class NotLoginException extends RuntimeException {
* @param type 类型 * @param type 类型
*/ */
public NotLoginException(String message, String loginKey, String type) { public NotLoginException(String message, String loginKey, String type) {
// 这里到底要不要拼接上login_key呢纠结
super(message); super(message);
this.loginKey = loginKey; this.loginKey = loginKey;
this.type = type; this.type = type;
@ -101,19 +100,19 @@ public class NotLoginException extends RuntimeException {
*/ */
public static NotLoginException newInstance(String loginKey, String type) { public static NotLoginException newInstance(String loginKey, String type) {
String message = null; String message = null;
if(type.equals(NOT_TOKEN)) { if(NOT_TOKEN.equals(type)) {
message = NOT_TOKEN_MESSAGE; message = NOT_TOKEN_MESSAGE;
} }
else if(type.equals(INVALID_TOKEN)) { else if(INVALID_TOKEN.equals(type)) {
message = INVALID_TOKEN_MESSAGE; message = INVALID_TOKEN_MESSAGE;
} }
else if(type.equals(TOKEN_TIMEOUT)) { else if(TOKEN_TIMEOUT.equals(type)) {
message = TOKEN_TIMEOUT_MESSAGE; message = TOKEN_TIMEOUT_MESSAGE;
} }
else if(type.equals(BE_REPLACED)) { else if(BE_REPLACED.equals(type)) {
message = BE_REPLACED_MESSAGE; message = BE_REPLACED_MESSAGE;
} }
else if(type.equals(KICK_OUT)) { else if(KICK_OUT.equals(type)) {
message = KICK_OUT_MESSAGE; message = KICK_OUT_MESSAGE;
} }
else { else {

View File

@ -4,48 +4,49 @@ import cn.dev33.satoken.stp.StpUtil;
/** /**
* 没有指定权限码抛出的异常 * 没有指定权限码抛出的异常
*
* @author kong * @author kong
* *
*/ */
public class NotPermissionException extends RuntimeException { public class NotPermissionException extends RuntimeException {
/** /**
* * 序列化版本号
*/ */
private static final long serialVersionUID = 6806129545290130142L; private static final long serialVersionUID = 6806129545290130142L;
/** 权限码 */ /** 权限码 */
private String code; private String code;
/** /**
* @return 获得权限码 * @return 获得权限码
*/ */
public String getCode() { public String getCode() {
return code; return code;
} }
/** /**
* loginKey * loginKey
*/ */
private String loginKey; private String loginKey;
/**
* 获得loginKey /**
* @return loginKey * 获得loginKey
*
* @return loginKey
*/ */
public String getLoginKey() { public String getLoginKey() {
return loginKey; return loginKey;
} }
public NotPermissionException(String code) { public NotPermissionException(String code) {
this(code, StpUtil.stpLogic.loginKey); this(code, StpUtil.stpLogic.loginKey);
} }
public NotPermissionException(String code, String loginKey) {
// 这里到底要不要拼接上loginKey呢纠结
super("无此权限:" + code);
this.code = code;
this.loginKey = loginKey;
}
public NotPermissionException(String code, String loginKey) {
super("无此权限:" + code);
this.code = code;
this.loginKey = loginKey;
}
} }

View File

@ -4,48 +4,50 @@ import cn.dev33.satoken.stp.StpUtil;
/** /**
* 没有指定角色标识抛出的异常 * 没有指定角色标识抛出的异常
*
* @author kong * @author kong
* *
*/ */
public class NotRoleException extends RuntimeException { public class NotRoleException extends RuntimeException {
/** /**
* * 序列化版本号
*/ */
private static final long serialVersionUID = 8243974276159004739L; private static final long serialVersionUID = 8243974276159004739L;
/** 角色标识 */ /** 角色标识 */
private String role; private String role;
/** /**
* @return 获得角色标识 * @return 获得角色标识
*/ */
public String getRole() { public String getRole() {
return role; return role;
} }
/** /**
* loginKey * loginKey
*/ */
private String loginKey; private String loginKey;
/**
* 获得loginKey /**
* @return loginKey * 获得loginKey
*
* @return loginKey
*/ */
public String getLoginKey() { public String getLoginKey() {
return loginKey; return loginKey;
} }
public NotRoleException(String role) { public NotRoleException(String role) {
this(role, StpUtil.stpLogic.loginKey); this(role, StpUtil.stpLogic.loginKey);
} }
public NotRoleException(String role, String loginKey) { public NotRoleException(String role, String loginKey) {
// 这里到底要不要拼接上loginKey呢纠结 // 这里到底要不要拼接上loginKey呢纠结
super("无此角色:" + role); super("无此角色:" + role);
this.role = role; this.role = role;
this.loginKey = loginKey; this.loginKey = loginKey;
} }
} }

View File

@ -1,33 +1,34 @@
package cn.dev33.satoken.exception; package cn.dev33.satoken.exception;
/** /**
* sa-token框架内部逻辑发生错误抛出的异常 * sa-token框架内部逻辑发生错误抛出的异常 (自定义此异常可方便开发者在做全局异常处理时分辨异常类型)
*
* @author kong * @author kong
* *
*/ */
public class SaTokenException extends RuntimeException { public class SaTokenException extends RuntimeException {
/** /**
* * 序列化版本号
*/ */
private static final long serialVersionUID = 6806129545290130132L; private static final long serialVersionUID = 6806129545290130132L;
/** /**
* 构建一个异常 * 构建一个异常
* @param message 异常描述信息 *
* @param message 异常描述信息
*/ */
public SaTokenException(String message) { public SaTokenException(String message) {
super(message); super(message);
} }
/** /**
* 构建一个异常 * 构建一个异常
* @param cause 异常对象 *
* @param cause 异常对象
*/ */
public SaTokenException(Throwable cause) { public SaTokenException(Throwable cause) {
super(cause); super(cause);
} }
} }

View File

@ -1,33 +1,36 @@
package cn.dev33.satoken.fun; package cn.dev33.satoken.fun;
/** /**
* 根据boolean变量决定是否执行一个函数 * 根据boolean变量决定是否执行一个函数
*
* @author kong * @author kong
* *
*/ */
public class IsRunFunction { public class IsRunFunction {
/** /**
* 变量 * 变量
*/ */
public Boolean isRun; public final Boolean isRun;
/** /**
* 设定一个变量如果为true则执行exe函数 * 设定一个变量如果为true则执行exe函数
*
* @param isRun 变量 * @param isRun 变量
*/ */
public IsRunFunction(boolean isRun) { public IsRunFunction(boolean isRun) {
this.isRun = isRun; this.isRun = isRun;
} }
/** /**
* 根据变量决定是否执行此函数 * 根据变量决定是否执行此函数
* @param function 函数 *
* @param function 函数
*/ */
public void exe(SaFunction function) { public void exe(SaFunction function) {
if(isRun) { if (isRun) {
function.run(); function.run();
} }
} }
} }

View File

@ -1,14 +1,15 @@
package cn.dev33.satoken.fun; package cn.dev33.satoken.fun;
/** /**
* 模拟身份方法的辅助类 * 设定一个函数方便在Lambda表达式下的函数式编程
*
* @author kong * @author kong
* *
*/ */
public interface SaFunction { public interface SaFunction {
/** /**
* 执行的方法 * 执行的方法
*/ */
public void run(); public void run();

View File

@ -4,24 +4,25 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
/** /**
* Servlet相关操作 * Servlet相关操作接口
*
* @author kong * @author kong
* *
*/ */
public interface SaTokenServlet { public interface SaTokenServlet {
/** /**
* 获取当前请求的 Request 对象 * 获取当前请求的 Request 对象
*
* @return 当前请求的Request对象 * @return 当前请求的Request对象
*/ */
public HttpServletRequest getRequest(); public HttpServletRequest getRequest();
/** /**
* 获取当前请求的 Response 对象 * 获取当前请求的 Response 对象
*
* @return 当前请求的response对象 * @return 当前请求的response对象
*/ */
public HttpServletResponse getResponse(); public HttpServletResponse getResponse();
} }

View File

@ -3,28 +3,30 @@ package cn.dev33.satoken.servlet;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import cn.dev33.satoken.exception.SaTokenException;
/** /**
* sa-token 对SaTokenServlet接口默认实现类 * sa-token 对SaTokenServlet接口默认实现类
*
* @author kong * @author kong
* *
*/ */
public class SaTokenServletDefaultImpl implements SaTokenServlet { public class SaTokenServletDefaultImpl implements SaTokenServlet {
/** /**
* 获取当前请求的Request对象 * 获取当前请求的Request对象
*/ */
@Override @Override
public HttpServletRequest getRequest() { public HttpServletRequest getRequest() {
throw new RuntimeException("请实现SaTokenServlet接口后进行Servlet相关操作"); throw new SaTokenException("请实现SaTokenServlet接口后进行Servlet相关操作");
} }
/** /**
* 获取当前请求的Response对象 * 获取当前请求的Response对象
*/ */
@Override @Override
public HttpServletResponse getResponse() { public HttpServletResponse getResponse() {
throw new RuntimeException("请实现SaTokenServlet接口后进行Servlet相关操作"); throw new SaTokenException("请实现SaTokenServlet接口后进行Servlet相关操作");
} }
} }

View File

@ -9,213 +9,222 @@ import java.util.concurrent.ConcurrentHashMap;
import cn.dev33.satoken.SaTokenManager; import cn.dev33.satoken.SaTokenManager;
/** /**
* session会话 * Session Model
*
* @author kong * @author kong
* *
*/ */
public class SaSession implements Serializable { public class SaSession implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** 此会话的id */ /** 此Session的id */
private String id; private String id;
/** 此会话的创建时间 */ /** 此Session的创建时间 */
private long createTime; private long createTime;
/** 此会话的所有数据 */ /** 此Session的所有挂载数据 */
private Map<String, Object> dataMap = new ConcurrentHashMap<String, Object>(); private Map<String, Object> dataMap = new ConcurrentHashMap<String, Object>();
/** /**
* 构建一个 session对象 * 构建一个Session对象
*/ */
public SaSession() {} public SaSession() {
/**
* 构建一个 session对象
* @param id session的id
*/
public SaSession(String id) {
this.id = id;
this.createTime = System.currentTimeMillis();
} }
/** /**
* 获取此会话id * 构建一个Session对象
* @return 此会话的id *
*/ * @param id Session的id
*/
public SaSession(String id) {
this.id = id;
this.createTime = System.currentTimeMillis();
}
/**
* 获取此会话id
*
* @return 此会话的id
*/
public String getId() { public String getId() {
return id; return id;
} }
/** /**
* 返回当前会话创建时间 * 返回当前会话创建时间
*
* @return 时间戳 * @return 时间戳
*/ */
public long getCreateTime() { public long getCreateTime() {
return createTime; return createTime;
} }
// ----------------------- TokenSign相关
// ----------------------- tokenSign相关
/** /**
* 本session绑定的token签名列表 * 此Session绑定的token签名列表
*/ */
private List<TokenSign> tokenSignList = new Vector<TokenSign>(); private List<TokenSign> tokenSignList = new Vector<TokenSign>();
/** /**
* 返回token签名列表 * 返回token签名列表的拷贝副本
*
* @return token签名列表 * @return token签名列表
*/ */
public List<TokenSign> getTokenSignList() { public List<TokenSign> getTokenSignList() {
return new Vector<>(tokenSignList); return new Vector<>(tokenSignList);
} }
/** /**
* 查找一个token签名 * 查找一个token签名
* @param tokenValue token值 *
* @param tokenValue token值
* @return 查找到的tokenSign * @return 查找到的tokenSign
*/ */
public TokenSign getTokenSign(String tokenValue) { public TokenSign getTokenSign(String tokenValue) {
for (TokenSign tokenSign : getTokenSignList()) { for (TokenSign tokenSign : getTokenSignList()) {
if(tokenSign.getValue().equals(tokenValue)){ if (tokenSign.getValue().equals(tokenValue)) {
return tokenSign; return tokenSign;
} }
} }
return null; return null;
} }
/** /**
* 添加一个token签名 * 添加一个token签名
*
* @param tokenSign token签名 * @param tokenSign token签名
*/ */
public void addTokenSign(TokenSign tokenSign) { public void addTokenSign(TokenSign tokenSign) {
// 如果已经存在于列表中则无需再次添加 // 如果已经存在于列表中则无需再次添加
for (TokenSign tokenSign2 : getTokenSignList()) { for (TokenSign tokenSign2 : getTokenSignList()) {
if(tokenSign2.getValue().equals(tokenSign.getValue())){ if (tokenSign2.getValue().equals(tokenSign.getValue())) {
return; return;
} }
} }
// 添加并更新 // 添加并更新
tokenSignList.add(tokenSign); tokenSignList.add(tokenSign);
update(); update();
} }
/** /**
* 移除一个token签名 * 移除一个token签名
* @param tokenValue token名称 *
* @param tokenValue token名称
*/ */
public void removeTokenSign(String tokenValue) { public void removeTokenSign(String tokenValue) {
TokenSign tokenSign = getTokenSign(tokenValue); TokenSign tokenSign = getTokenSign(tokenValue);
if(tokenSignList.remove(tokenSign)) { if (tokenSignList.remove(tokenSign)) {
update(); update();
} }
} }
// ----------------------- 存取值
// ----------------------- 存取值
/** /**
* 写入一个值 * 写入一个值
* @param key 名称 *
* @param value * @param key 名称
* @param value
*/ */
public void setAttribute(String key, Object value) { public void setAttribute(String key, Object value) {
dataMap.put(key, value); dataMap.put(key, value);
update(); update();
} }
/** /**
* 取出一个值 * 取出一个值
*
* @param key 名称 * @param key 名称
* @return * @return
*/ */
public Object getAttribute(String key) { public Object getAttribute(String key) {
return dataMap.get(key); return dataMap.get(key);
} }
/** /**
* 取值并指定取不到值时的默认值 * 取值并指定取不到值时的默认值
* @param key 名称 *
* @param defaultValue 取不到值的时候返回的默认值 * @param key 名称
* @param defaultValue 取不到值的时候返回的默认值
* @return value * @return value
*/ */
public Object getAttribute(String key, Object defaultValue) { public Object getAttribute(String key, Object defaultValue) {
Object value = getAttribute(key); Object value = getAttribute(key);
if(value != null) { if (value != null) {
return value; return value;
} }
return defaultValue; return defaultValue;
} }
/** /**
* 移除一个值 * 移除一个值
*
* @param key 要移除的值的名字 * @param key 要移除的值的名字
*/ */
public void removeAttribute(String key) { public void removeAttribute(String key) {
dataMap.remove(key); dataMap.remove(key);
update(); update();
} }
/** /**
* 清空所有值 * 清空所有值
*/ */
public void clearAttribute() { public void clearAttribute() {
dataMap.clear(); dataMap.clear();
update(); update();
} }
/** /**
* 是否含有指定key * 是否含有指定key
* @param key 是否含有指定值 *
* @return 是否含有 * @param key 是否含有指定值
* @return 是否含有
*/ */
public boolean containsAttribute(String key) { public boolean containsAttribute(String key) {
return dataMap.keySet().contains(key); return dataMap.keySet().contains(key);
} }
/** /**
* 返回当前session会话所有key * 返回当前session会话所有key
* @return 所有值的key列表 *
* @return 所有值的key列表
*/ */
public Set<String> attributeKeys() { public Set<String> attributeKeys() {
return dataMap.keySet(); return dataMap.keySet();
} }
/** /**
* 获取数据集合如果更新map里的值请调用session.update()方法避免数据过时 * 获取数据挂载集合如果更新map里的值请调用session.update()方法避免产生脏数据
* @return 返回底层储存值的map对象 *
* @return 返回底层储存值的map对象
*/ */
public Map<String, Object> getDataMap() { public Map<String, Object> getDataMap() {
return dataMap; return dataMap;
} }
// ----------------------- 一些操作
// ----------------------- 一些操作
/** /**
* 将这个session从持久库更新一下 * 将这个Session从持久库更新一下
*/ */
public void update() { public void update() {
SaTokenManager.getSaTokenDao().updateSession(this); SaTokenManager.getSaTokenDao().updateSession(this);
} }
/** 注销会话(注销后此session会话将不再存储服务器上) */ /** 注销会话 (注销后此session会话将不再存储服务器上) */
public void logout() { public void logout() {
SaTokenManager.getSaTokenDao().deleteSession(this.id); SaTokenManager.getSaTokenDao().deleteSession(this.id);
} }
/** 如果这个token的tokenSign数量为零则直接注销会话 */ /** 当Session上的tokenSign数量为零时注销会话 */
public void logoutByTokenSignCountToZero() { public void logoutByTokenSignCountToZero() {
if(tokenSignList.size() == 0) { if (tokenSignList.size() == 0) {
logout(); logout();
} }
} }
} }

View File

@ -3,68 +3,71 @@ package cn.dev33.satoken.session;
import cn.dev33.satoken.SaTokenManager; import cn.dev33.satoken.SaTokenManager;
/** /**
* 自定义sa-session工具类 * 自定义Session工具类
*
* @author kong * @author kong
* *
*/ */
public class SaSessionCustomUtil { public class SaSessionCustomUtil {
/** /**
* 添加上指定前缀防止恶意伪造session * 添加上指定前缀防止恶意伪造session
*/ */
public static String sessionKey = "custom"; public static String sessionKey = "custom";
/** /**
* 组织一下自定义session的id * 组织一下自定义Session的id
*
* @param sessionId 会话id * @param sessionId 会话id
* @return sessionId * @return sessionId
*/ */
public static String getSessionKey(String sessionId) { public static String getSessionKey(String sessionId) {
return SaTokenManager.getConfig().getTokenName() + ":" + sessionKey + ":session:" + sessionId; return SaTokenManager.getConfig().getTokenName() + ":" + sessionKey + ":session:" + sessionId;
} }
/**
/** * 验证指定key的Session是否存在
* 指定key的session是否存在 *
* @param sessionId session的id * @param sessionId session的id
* @return 是否存在 * @return 是否存在
*/ */
public boolean isExists(String sessionId) { public boolean isExists(String sessionId) {
return SaTokenManager.getSaTokenDao().getSession(getSessionKey(sessionId)) != null; return SaTokenManager.getSaTokenDao().getSession(getSessionKey(sessionId)) != null;
} }
/** /**
* 获取指定key的session * 获取指定key的Session
*
* @param sessionId key * @param sessionId key
* @param isCreate 如果没有是否新建并返回 * @param isCreate 如果此Session尚未在DB创建是否新建并返回
* @return SaSession * @return SaSession
*/ */
public static SaSession getSessionById(String sessionId, boolean isCreate) { public static SaSession getSessionById(String sessionId, boolean isCreate) {
SaSession session = SaTokenManager.getSaTokenDao().getSession(getSessionKey(sessionId)); SaSession session = SaTokenManager.getSaTokenDao().getSession(getSessionKey(sessionId));
if(session == null && isCreate) { if (session == null && isCreate) {
session = new SaSession(getSessionKey(sessionId)); session = new SaSession(getSessionKey(sessionId));
SaTokenManager.getSaTokenDao().saveSession(session, SaTokenManager.getConfig().getTimeout()); SaTokenManager.getSaTokenDao().saveSession(session, SaTokenManager.getConfig().getTimeout());
} }
return session; return session;
} }
/** /**
* 获取指定key的session, 如果没有则新建并返回 * 获取指定key的Session, 如果此Session尚未在DB创建则新建并返回
*
* @param sessionId key * @param sessionId key
* @return session对象 * @return session对象
*/ */
public static SaSession getSessionById(String sessionId) { public static SaSession getSessionById(String sessionId) {
return getSessionById(sessionId, true); return getSessionById(sessionId, true);
} }
/** /**
* 删除指定key的session * 删除指定key的session
* @param sessionId 删除指定key *
* @param sessionId 指定key
*/ */
public static void deleteSessionById(String sessionId) { public static void deleteSessionById(String sessionId) {
SaTokenManager.getSaTokenDao().deleteSession(getSessionKey(sessionId)); SaTokenManager.getSaTokenDao().deleteSession(getSessionKey(sessionId));
} }
} }

View File

@ -3,66 +3,62 @@ package cn.dev33.satoken.session;
import java.io.Serializable; import java.io.Serializable;
/** /**
* 挂在到SaSession上的token签名 * token签名 Model
*
* 挂在到SaSession上的token签名
*
* @author kong * @author kong
* *
*/ */
public class TokenSign implements Serializable { public class TokenSign implements Serializable {
/** /**
* *
*/ */
private static final long serialVersionUID = 1406115065849845073L; private static final long serialVersionUID = 1406115065849845073L;
/** /**
* token值 * token值
*/ */
private String value; private String value;
/** /**
* 所在设备标识 * 所在设备标识
*/ */
private String device; private String device;
/** 构建一个 */ /** 构建一个 */
public TokenSign() {} public TokenSign() {
/**
* 构建一个
* @param value token值
* @param device 所在设备标识
*/
public TokenSign(String value, String device) {
this.value = value;
this.device = device;
} }
/** /**
* @return value * 构建一个
*
* @param value token值
* @param device 所在设备标识
*/
public TokenSign(String value, String device) {
this.value = value;
this.device = device;
}
/**
* @return token value
*/ */
public String getValue() { public String getValue() {
return value; return value;
} }
/** /**
* @return device * @return token登录设备
*/ */
public String getDevice() { public String getDevice() {
return device; return device;
} }
@Override @Override
public String toString() { public String toString() {
return "TokenSign [value=" + value + ", device=" + device + "]"; return "TokenSign [value=" + value + ", device=" + device + "]";
} }
} }

View File

@ -1,7 +1,8 @@
package cn.dev33.satoken.stp; package cn.dev33.satoken.stp;
/** /**
* 用来描述一个token常用信息的类 * token信息Model: 用来描述一个token的常用参数
*
* @author kong * @author kong
* *
*/ */
@ -13,177 +14,173 @@ public class SaTokenInfo {
/** token值 */ /** token值 */
public String tokenValue; public String tokenValue;
/** 当前是否已经登录 */ /** 此token是否已经登录 */
public Boolean isLogin; public Boolean isLogin;
/** 当前loginId未登录时为null */ /** 此token对应的LoginId未登录时为null */
public Object loginId; public Object loginId;
/** 当前loginKey */ /** LoginKey账号体系标识 */
public String loginKey; public String loginKey;
/** token剩余有效期 (单位: 秒) */ /** token剩余有效期 (单位: 秒) */
public long tokenTimeout; public long tokenTimeout;
/** session剩余有效时间 (单位: 秒) */ /** User-Session剩余有效时间 (单位: 秒) */
public long sessionTimeout; public long sessionTimeout;
/** token专属session剩余有效时间 (单位: 秒) */ /** Token-Session剩余有效时间 (单位: 秒) */
public long tokenSessionTimeout; public long tokenSessionTimeout;
/** /** token剩余无操作有效时间 (单位: 秒) */
* token剩余无操作有效时间
*/
public long tokenActivityTimeout; public long tokenActivityTimeout;
/** 当前登录设备 */ /** 登录设备标识 */
public String loginDevice; public String loginDevice;
/** /**
* @return tokenName * @return token名称
*/ */
public String getTokenName() { public String getTokenName() {
return tokenName; return tokenName;
} }
/** /**
* @param tokenName 要设置的 tokenName * @param tokenName token名称
*/ */
public void setTokenName(String tokenName) { public void setTokenName(String tokenName) {
this.tokenName = tokenName; this.tokenName = tokenName;
} }
/** /**
* @return tokenValue * @return token
*/ */
public String getTokenValue() { public String getTokenValue() {
return tokenValue; return tokenValue;
} }
/** /**
* @param tokenValue 要设置的 tokenValue * @param tokenValue token值
*/ */
public void setTokenValue(String tokenValue) { public void setTokenValue(String tokenValue) {
this.tokenValue = tokenValue; this.tokenValue = tokenValue;
} }
/** /**
* @return isLogin * @return 此token是否已经登录
*/ */
public Boolean getIsLogin() { public Boolean getIsLogin() {
return isLogin; return isLogin;
} }
/** /**
* @param isLogin 要设置的 isLogin * @param isLogin 此token是否已经登录
*/ */
public void setIsLogin(Boolean isLogin) { public void setIsLogin(Boolean isLogin) {
this.isLogin = isLogin; this.isLogin = isLogin;
} }
/** /**
* @return loginId * @return 此token对应的LoginId未登录时为null
*/ */
public Object getLoginId() { public Object getLoginId() {
return loginId; return loginId;
} }
/** /**
* @param loginId 要设置的 loginId * @param loginId 此token对应的LoginId未登录时为null
*/ */
public void setLoginId(Object loginId) { public void setLoginId(Object loginId) {
this.loginId = loginId; this.loginId = loginId;
} }
/** /**
* @return loginKey * @return LoginKey账号体系标识
*/ */
public String getLoginKey() { public String getLoginKey() {
return loginKey; return loginKey;
} }
/** /**
* @param loginKey 要设置的 loginKey * @param loginKey LoginKey账号体系标识
*/ */
public void setLoginKey(String loginKey) { public void setLoginKey(String loginKey) {
this.loginKey = loginKey; this.loginKey = loginKey;
} }
/** /**
* @return tokenTimeout * @return token剩余有效期 (单位: )
*/ */
public long getTokenTimeout() { public long getTokenTimeout() {
return tokenTimeout; return tokenTimeout;
} }
/** /**
* @param tokenTimeout 要设置的 tokenTimeout * @param tokenTimeout token剩余有效期 (单位: )
*/ */
public void setTokenTimeout(long tokenTimeout) { public void setTokenTimeout(long tokenTimeout) {
this.tokenTimeout = tokenTimeout; this.tokenTimeout = tokenTimeout;
} }
/** /**
* @return sessionTimeout * @return User-Session剩余有效时间 (单位: )
*/ */
public long getSessionTimeout() { public long getSessionTimeout() {
return sessionTimeout; return sessionTimeout;
} }
/** /**
* @param sessionTimeout 要设置的 sessionTimeout * @param sessionTimeout User-Session剩余有效时间 (单位: )
*/ */
public void setSessionTimeout(long sessionTimeout) { public void setSessionTimeout(long sessionTimeout) {
this.sessionTimeout = sessionTimeout; this.sessionTimeout = sessionTimeout;
} }
/** /**
* @return tokenSessionTimeout * @return Token-Session剩余有效时间 (单位: )
*/ */
public long getTokenSessionTimeout() { public long getTokenSessionTimeout() {
return tokenSessionTimeout; return tokenSessionTimeout;
} }
/** /**
* @param tokenSessionTimeout 要设置的 tokenSessionTimeout * @param tokenSessionTimeout Token-Session剩余有效时间 (单位: )
*/ */
public void setTokenSessionTimeout(long tokenSessionTimeout) { public void setTokenSessionTimeout(long tokenSessionTimeout) {
this.tokenSessionTimeout = tokenSessionTimeout; this.tokenSessionTimeout = tokenSessionTimeout;
} }
/** /**
* @return tokenActivityTimeout * @return token剩余无操作有效时间 (单位: )
*/ */
public long getTokenActivityTimeout() { public long getTokenActivityTimeout() {
return tokenActivityTimeout; return tokenActivityTimeout;
} }
/** /**
* @param tokenActivityTimeout 要设置的 tokenActivityTimeout * @param tokenActivityTimeout token剩余无操作有效时间 (单位: )
*/ */
public void setTokenActivityTimeout(long tokenActivityTimeout) { public void setTokenActivityTimeout(long tokenActivityTimeout) {
this.tokenActivityTimeout = tokenActivityTimeout; this.tokenActivityTimeout = tokenActivityTimeout;
} }
/** /**
* @return loginDevice * @return 登录设备标识
*/ */
public String getLoginDevice() { public String getLoginDevice() {
return loginDevice; return loginDevice;
} }
/** /**
* @param loginDevice 要设置的 loginDevice * @param loginDevice 登录设备标识
*/ */
public void setLoginDevice(String loginDevice) { public void setLoginDevice(String loginDevice) {
this.loginDevice = loginDevice; this.loginDevice = loginDevice;
} }
/**
* toString
*/
@Override @Override
public String toString() { public String toString() {
return "SaTokenInfo [tokenName=" + tokenName + ", tokenValue=" + tokenValue + ", isLogin=" + isLogin return "SaTokenInfo [tokenName=" + tokenName + ", tokenValue=" + tokenValue + ", isLogin=" + isLogin
@ -191,18 +188,5 @@ public class SaTokenInfo {
+ ", sessionTimeout=" + sessionTimeout + ", tokenSessionTimeout=" + tokenSessionTimeout + ", sessionTimeout=" + sessionTimeout + ", tokenSessionTimeout=" + tokenSessionTimeout
+ ", tokenActivityTimeout=" + tokenActivityTimeout + ", loginDevice=" + loginDevice + "]"; + ", tokenActivityTimeout=" + tokenActivityTimeout + ", loginDevice=" + loginDevice + "]";
} }
} }

View File

@ -3,26 +3,28 @@ package cn.dev33.satoken.stp;
import java.util.List; import java.util.List;
/** /**
* 开放权限验证接口方便重写 * 权限认证接口实现此接口即可集成权限认证功能
*
* @author kong * @author kong
*/ */
public interface StpInterface { public interface StpInterface {
/** /**
* 返回指定loginId所拥有的权限码集合 * 返回指定 LoginId 所拥有的权限码集合
* @param loginId 账号id *
* @param loginKey 具体的stp标识 * @param loginId 账号id
* @return 该账号id具有的权限码集合 * @param loginKey 账号体系标识
* @return 该账号id具有的权限码集合
*/ */
public List<String> getPermissionList(Object loginId, String loginKey); public List<String> getPermissionList(Object loginId, String loginKey);
/** /**
* 返回指定loginId所拥有的角色标识集合 * 返回指定loginId所拥有的角色标识集合
* @param loginId 账号id *
* @param loginKey 具体的stp标识 * @param loginId 账号id
* @return 该账号id具有的角色标识集合 * @param loginKey 账号体系标识
* @return 该账号id具有的角色标识集合
*/ */
public List<String> getRoleList(Object loginId, String loginKey); public List<String> getRoleList(Object loginId, String loginKey);
} }

View File

@ -4,7 +4,10 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
* 对StpInterface接口默认的实现类 * 对StpInterface接口默认的实现类
* <p>
* 如果开发者没有实现StpInterface接口则使用此默认实现
*
* @author kong * @author kong
*/ */
public class StpInterfaceDefaultImpl implements StpInterface { public class StpInterfaceDefaultImpl implements StpInterface {

View File

@ -38,15 +38,15 @@ public class StpLogic {
public String loginKey = ""; public String loginKey = "";
/** /**
* 初始化StpLogic, 制定loginKey * 初始化StpLogic, 指定LoginKey
* @param loginKey 账号标识 * @param loginKey 账号体系标识
*/ */
public StpLogic(String loginKey) { public StpLogic(String loginKey) {
this.loginKey = loginKey; this.loginKey = loginKey;
} }
/** /**
* 获取当前StpLogin的loginKey * 获取当前StpLogin的LoginKey
* @return 当前StpLogin的loginKey * @return 当前StpLogin的loginKey
*/ */
public String getLoginKey(){ public String getLoginKey(){
@ -54,7 +54,7 @@ public class StpLogic {
} }
/** /**
* 写入当前StpLogin的loginKey * 写入当前StpLogin的LoginKey
* @param loginKey loginKey * @param loginKey loginKey
* @return 对象自身 * @return 对象自身
*/ */
@ -75,17 +75,16 @@ public class StpLogic {
} }
/** /**
* 随机生成一个tokenValue * 创建一个tokenValue
* @param loginId loginId * @param loginId loginId
* @return 生成的tokenValue * @return 生成的tokenValue
*/ */
public String createTokenValue(Object loginId) { public String createTokenValue(Object loginId) {
// 去除掉所有逗号 return SaTokenManager.getSaTokenAction().createToken(loginId, loginKey);
return SaTokenManager.getSaTokenAction().createToken(loginId, loginKey).replaceAll(",", "");
} }
/** /**
* 获取当前tokenValue * 获取当前tokenValue
* @return 当前tokenValue * @return 当前tokenValue
*/ */
public String getTokenValue(){ public String getTokenValue(){
@ -100,15 +99,15 @@ public class StpLogic {
tokenValue = String.valueOf(request.getAttribute(getKeyJustCreatedSave())); tokenValue = String.valueOf(request.getAttribute(getKeyJustCreatedSave()));
} }
// 2. 尝试从请求体里面读取 // 2. 尝试从请求体里面读取
if(tokenValue == null && config.getIsReadBody() == true){ if(tokenValue == null && config.getIsReadBody()){
tokenValue = request.getParameter(keyTokenName); tokenValue = request.getParameter(keyTokenName);
} }
// 3. 尝试从header里读取 // 3. 尝试从header里读取
if(tokenValue == null && config.getIsReadHead() == true){ if(tokenValue == null && config.getIsReadHead()){
tokenValue = request.getHeader(keyTokenName); tokenValue = request.getHeader(keyTokenName);
} }
// 4. 尝试从cookie里读取 // 4. 尝试从cookie里读取
if(tokenValue == null && config.getIsReadCookie() == true){ if(tokenValue == null && config.getIsReadCookie()){
Cookie cookie = SaTokenManager.getSaTokenCookie().getCookie(request, keyTokenName); Cookie cookie = SaTokenManager.getSaTokenCookie().getCookie(request, keyTokenName);
if(cookie != null){ if(cookie != null){
tokenValue = cookie.getValue(); tokenValue = cookie.getValue();
@ -156,7 +155,6 @@ public class StpLogic {
*/ */
public void setLoginId(Object loginId, String device) { public void setLoginId(Object loginId, String device) {
// ------ 1获取相应对象 // ------ 1获取相应对象
HttpServletRequest request = SaTokenManager.getSaTokenServlet().getRequest(); HttpServletRequest request = SaTokenManager.getSaTokenServlet().getRequest();
SaTokenConfig config = getConfig(); SaTokenConfig config = getConfig();
@ -166,7 +164,7 @@ public class StpLogic {
String tokenValue = null; String tokenValue = null;
// --- 如果允许并发登录 // --- 如果允许并发登录
if(config.getAllowConcurrentLogin() == true) { if(config.getAllowConcurrentLogin() == true) {
// 如果配置为共享token, 则尝试从session签名记录里取出token // 如果配置为共享token, 则尝试从Session签名记录里取出token
if(config.getIsShare() == true) { if(config.getIsShare() == true) {
tokenValue = getTokenValueByLoginId(loginId, device); tokenValue = getTokenValueByLoginId(loginId, device);
} }
@ -178,19 +176,22 @@ public class StpLogic {
List<TokenSign> tokenSignList = session.getTokenSignList(); List<TokenSign> tokenSignList = session.getTokenSignList();
for (TokenSign tokenSign : tokenSignList) { for (TokenSign tokenSign : tokenSignList) {
if(tokenSign.getDevice().equals(device)) { if(tokenSign.getDevice().equals(device)) {
dao.updateValue(getKeyTokenValue(tokenSign.getValue()), NotLoginException.BE_REPLACED); // 1. 将此token 标记为已顶替 // 1. 将此token 标记为已顶替
clearLastActivity(tokenSign.getValue()); // 2. 清理掉[token-最后操作时间] dao.updateValue(getKeyTokenValue(tokenSign.getValue()), NotLoginException.BE_REPLACED);
session.removeTokenSign(tokenSign.getValue()); // 3. 清理账号session上的token签名记录 // 2. 清理掉[token-最后操作时间]
clearLastActivity(tokenSign.getValue());
// 3. 清理账号session上的token签名记录
session.removeTokenSign(tokenSign.getValue());
} }
} }
} }
} }
// 如果至此仍未成功创建tokenValue // 如果至此仍未成功创建tokenValue, 则开始生成一个
if(tokenValue == null) { if(tokenValue == null) {
tokenValue = createTokenValue(loginId); tokenValue = createTokenValue(loginId);
} }
// ------ 3. 获取[id-session] (如果还没有创建session, 则新建, 如果已经创建则续期) // ------ 3. 获取[User-Session] (如果还没有创建session, 则新建, 如果已经创建则续期)
SaSession session = getSessionByLoginId(loginId, false); SaSession session = getSessionByLoginId(loginId, false);
if(session == null) { if(session == null) {
session = getSessionByLoginId(loginId); session = getSessionByLoginId(loginId);
@ -201,10 +202,14 @@ public class StpLogic {
session.addTokenSign(new TokenSign(tokenValue, device)); session.addTokenSign(new TokenSign(tokenValue, device));
// ------ 4. 持久化其它数据 // ------ 4. 持久化其它数据
dao.setValue(getKeyTokenValue(tokenValue), String.valueOf(loginId), config.getTimeout()); // token -> uid // token -> uid
request.setAttribute(getKeyJustCreatedSave(), tokenValue); // 将token保存到本次request里 dao.setValue(getKeyTokenValue(tokenValue), String.valueOf(loginId), config.getTimeout());
setLastActivityToNow(tokenValue); // 写入 [最后操作时间] // 将token保存到本次request里
if(config.getIsReadCookie() == true){ // cookie注入 request.setAttribute(getKeyJustCreatedSave(), tokenValue);
// 写入 [最后操作时间]
setLastActivityToNow(tokenValue);
// cookie注入
if(config.getIsReadCookie() == true){
SaTokenManager.getSaTokenCookie().addCookie(SaTokenManager.getSaTokenServlet().getResponse(), getTokenName(), tokenValue, "/", (int)config.getTimeout()); SaTokenManager.getSaTokenCookie().addCookie(SaTokenManager.getSaTokenServlet().getResponse(), getTokenName(), tokenValue, "/", (int)config.getTimeout());
} }
} }
@ -240,14 +245,14 @@ public class StpLogic {
} }
SaTokenManager.getSaTokenDao().deleteKey(getKeyTokenValue(tokenValue)); SaTokenManager.getSaTokenDao().deleteKey(getKeyTokenValue(tokenValue));
// 2. 尝试清理账号session上的token签名 (如果为null或已被标记为异常, 那么无需继续执行 ) // 3. 尝试清理账号session上的token签名 (如果为null或已被标记为异常, 那么无需继续执行 )
SaSession session = getSessionByLoginId(loginId, false); SaSession session = getSessionByLoginId(loginId, false);
if(session == null) { if(session == null) {
return; return;
} }
session.removeTokenSign(tokenValue); session.removeTokenSign(tokenValue);
// 3. 尝试注销session // 4. 尝试注销session
session.logoutByTokenSignCountToZero(); session.logoutByTokenSignCountToZero();
} }
@ -267,13 +272,13 @@ public class StpLogic {
* @param device 设备标识 (填null代表所有注销设备) * @param device 设备标识 (填null代表所有注销设备)
*/ */
public void logoutByLoginId(Object loginId, String device) { public void logoutByLoginId(Object loginId, String device) {
// 先获取这个账号的[id-session], 如果为null则不执行任何操作 // 1. 先获取这个账号的[id-session], 如果为null则不执行任何操作
SaSession session = getSessionByLoginId(loginId); SaSession session = getSessionByLoginId(loginId);
if(session == null) { if(session == null) {
return; return;
} }
// 循环token签名列表开始删除相关信息 // 2. 循环token签名列表开始删除相关信息
List<TokenSign> tokenSignList = session.getTokenSignList(); List<TokenSign> tokenSignList = session.getTokenSignList();
for (TokenSign tokenSign : tokenSignList) { for (TokenSign tokenSign : tokenSignList) {
if(device == null || tokenSign.getDevice().equals(device)) { if(device == null || tokenSign.getDevice().equals(device)) {
@ -282,12 +287,12 @@ public class StpLogic {
// 2. 清理掉[token-最后操作时间] // 2. 清理掉[token-最后操作时间]
clearLastActivity(tokenValue); clearLastActivity(tokenValue);
// 3. 标记已被踢下线 // 3. 标记已被踢下线
SaTokenManager.getSaTokenDao().updateValue(getKeyTokenValue(tokenValue), NotLoginException.KICK_OUT); // 标记已被踢下线 SaTokenManager.getSaTokenDao().updateValue(getKeyTokenValue(tokenValue), NotLoginException.KICK_OUT);
// 4. 清理账号session上的token签名 // 4. 清理账号session上的token签名
session.removeTokenSign(tokenValue); session.removeTokenSign(tokenValue);
} }
} }
// 尝试注销session // 3. 尝试注销session
session.logoutByTokenSignCountToZero(); session.logoutByTokenSignCountToZero();
} }
@ -314,16 +319,16 @@ public class StpLogic {
* @return 账号id * @return 账号id
*/ */
public Object getLoginId() { public Object getLoginId() {
// 如果正在[临时身份切换] // 如果正在[临时身份切换], 则返回临时身份
if(isSwitch()) { if(isSwitch()) {
return getSwitchLoginId(); return getSwitchLoginId();
} }
// 如果获取不到token则抛出无token // 如果获取不到token则抛出: 无token
String tokenValue = getTokenValue(); String tokenValue = getTokenValue();
if(tokenValue == null) { if(tokenValue == null) {
throw NotLoginException.newInstance(loginKey, NotLoginException.NOT_TOKEN); throw NotLoginException.newInstance(loginKey, NotLoginException.NOT_TOKEN);
} }
// 查找此token对应loginId, 则抛出无效token // 查找此token对应loginId, 如果找不到则抛出无效token
String loginId = getLoginIdNotHandle(tokenValue); String loginId = getLoginIdNotHandle(tokenValue);
if(loginId == null) { if(loginId == null) {
throw NotLoginException.newInstance(loginKey, NotLoginException.INVALID_TOKEN); throw NotLoginException.newInstance(loginKey, NotLoginException.INVALID_TOKEN);
@ -336,14 +341,14 @@ public class StpLogic {
if(loginId.equals(NotLoginException.BE_REPLACED)) { if(loginId.equals(NotLoginException.BE_REPLACED)) {
throw NotLoginException.newInstance(loginKey, NotLoginException.BE_REPLACED); throw NotLoginException.newInstance(loginKey, NotLoginException.BE_REPLACED);
} }
// 如果是已经被踢下线了, 则抛出已被踢下线 // 如果是已经被踢下线了, 则抛出已被踢下线
if(loginId.equals(NotLoginException.KICK_OUT)) { if(loginId.equals(NotLoginException.KICK_OUT)) {
throw NotLoginException.newInstance(loginKey, NotLoginException.KICK_OUT); throw NotLoginException.newInstance(loginKey, NotLoginException.KICK_OUT);
} }
// 检查是否已经 [临时过期]同时更新[最后操作时间] // 检查是否已经 [临时过期]同时更新[最后操作时间]
checkActivityTimeout(tokenValue); checkActivityTimeout(tokenValue);
updateLastActivityToNow(tokenValue); updateLastActivityToNow(tokenValue);
// 至此返回loginId // 至此返回loginId
return loginId; return loginId;
} }
@ -387,7 +392,7 @@ public class StpLogic {
if(tokenValue == null) { if(tokenValue == null) {
return null; return null;
} }
// loginId为null或者在异常项里面均视为未登录 // loginId为null或者在异常项里面均视为未登录, 返回null
Object loginId = getLoginIdNotHandle(tokenValue); Object loginId = getLoginIdNotHandle(tokenValue);
if(loginId == null || NotLoginException.ABNORMAL_LIST.contains(loginId)) { if(loginId == null || NotLoginException.ABNORMAL_LIST.contains(loginId)) {
return null; return null;
@ -413,10 +418,6 @@ public class StpLogic {
* @return 账号id * @return 账号id
*/ */
public int getLoginIdAsInt() { public int getLoginIdAsInt() {
// Object loginId = getLoginId();
// if(loginId instanceof Integer) {
// return (Integer)loginId;
// }
return Integer.valueOf(String.valueOf(getLoginId())); return Integer.valueOf(String.valueOf(getLoginId()));
} }
@ -425,10 +426,6 @@ public class StpLogic {
* @return 账号id * @return 账号id
*/ */
public long getLoginIdAsLong() { public long getLoginIdAsLong() {
// Object loginId = getLoginId();
// if(loginId instanceof Long) {
// return (Long)loginId;
// }
return Long.valueOf(String.valueOf(getLoginId())); return Long.valueOf(String.valueOf(getLoginId()));
} }
@ -553,11 +550,14 @@ public class StpLogic {
// 如果配置忽略token登录校验则必须保证token不为null (token为null的时候随机创建一个) // 如果配置忽略token登录校验则必须保证token不为null (token为null的时候随机创建一个)
String tokenValue = getTokenValue(); String tokenValue = getTokenValue();
if(tokenValue == null || Objects.equals(tokenValue, "")) { if(tokenValue == null || Objects.equals(tokenValue, "")) {
// 随机一个token送给ta // 随机一个token送给Ta
tokenValue = createTokenValue(null); tokenValue = createTokenValue(null);
// Request做上标记
SaTokenManager.getSaTokenServlet().getRequest().setAttribute(getKeyJustCreatedSave(), tokenValue); SaTokenManager.getSaTokenServlet().getRequest().setAttribute(getKeyJustCreatedSave(), tokenValue);
setLastActivityToNow(tokenValue); // 写入 [最后操作时间] // 写入 [最后操作时间]
if(getConfig().getIsReadCookie() == true){ // cookie注入 setLastActivityToNow(tokenValue);
// cookie注入
if(getConfig().getIsReadCookie() == true){
SaTokenManager.getSaTokenCookie().addCookie(SaTokenManager.getSaTokenServlet().getResponse(), getTokenName(), tokenValue, "/", (int)getConfig().getTimeout()); SaTokenManager.getSaTokenCookie().addCookie(SaTokenManager.getSaTokenServlet().getResponse(), getTokenName(), tokenValue, "/", (int)getConfig().getTimeout());
} }
} }
@ -801,7 +801,7 @@ public class StpLogic {
List<String> roleList = SaTokenManager.getStpInterface().getRoleList(loginId, loginKey); List<String> roleList = SaTokenManager.getStpInterface().getRoleList(loginId, loginKey);
for (String role : roleArray) { for (String role : roleArray) {
if(roleList.contains(role) == false) { if(roleList.contains(role) == false) {
throw new NotRoleException(role, this.loginKey); // 没有权限抛出异常 throw new NotRoleException(role, this.loginKey);
} }
} }
} }
@ -815,11 +815,12 @@ public class StpLogic {
List<String> roleList = SaTokenManager.getStpInterface().getRoleList(loginId, loginKey); List<String> roleList = SaTokenManager.getStpInterface().getRoleList(loginId, loginKey);
for (String role : roleArray) { for (String role : roleArray) {
if(roleList.contains(role) == true) { if(roleList.contains(role) == true) {
return; // 有的话提前退出 // 有的话提前退出
return;
} }
} }
if(roleArray.length > 0) { if(roleArray.length > 0) {
throw new NotRoleException(roleArray[0], this.loginKey); // 没有权限抛出异常 throw new NotRoleException(roleArray[0], this.loginKey);
} }
} }
@ -865,7 +866,7 @@ public class StpLogic {
List<String> permissionList = SaTokenManager.getStpInterface().getPermissionList(loginId, loginKey); List<String> permissionList = SaTokenManager.getStpInterface().getPermissionList(loginId, loginKey);
for (String permission : permissionArray) { for (String permission : permissionArray) {
if(permissionList.contains(permission) == false) { if(permissionList.contains(permission) == false) {
throw new NotPermissionException(permission, this.loginKey); // 没有权限抛出异常 throw new NotPermissionException(permission, this.loginKey);
} }
} }
} }
@ -879,11 +880,12 @@ public class StpLogic {
List<String> permissionList = SaTokenManager.getStpInterface().getPermissionList(loginId, loginKey); List<String> permissionList = SaTokenManager.getStpInterface().getPermissionList(loginId, loginKey);
for (String permission : permissionArray) { for (String permission : permissionArray) {
if(permissionList.contains(permission) == true) { if(permissionList.contains(permission) == true) {
return; // 有的话提前退出 // 有的话提前退出
return;
} }
} }
if(permissionArray.length > 0) { if(permissionArray.length > 0) {
throw new NotPermissionException(permissionArray[0], this.loginKey); // 没有权限抛出异常 throw new NotPermissionException(permissionArray[0], this.loginKey);
} }
} }

View File

@ -37,7 +37,7 @@ public class StpUtil {
} }
/** /**
* 获取当前tokenValue * 获取当前tokenValue
* @return 当前tokenValue * @return 当前tokenValue
*/ */
public static String getTokenValue() { public static String getTokenValue() {

View File

@ -51,6 +51,9 @@ public class SaTaskUtil {
* @author kong * @author kong
*/ */
public static interface FunctionRunClass{ public static interface FunctionRunClass{
/**
* 要执行的方法
*/
public void run(); public void run();
} }

View File

@ -1,12 +1,15 @@
package cn.dev33.satoken.util; package cn.dev33.satoken.util;
/** /**
* 定义sa-token的所有常量 * sa-token常量
* @author kong * @author kong
* *
*/ */
public class SaTokenConsts { public class SaTokenConsts {
// =================== sa-token版本信息 ===================
/** /**
* sa-token 版本号 * sa-token 版本号
*/ */
@ -16,29 +19,62 @@ public class SaTokenConsts {
* sa-token 开源地址 * sa-token 开源地址
*/ */
public static final String GITHUB_URL = "https://github.com/click33/sa-token"; public static final String GITHUB_URL = "https://github.com/click33/sa-token";
// =================== 常量key标记 ===================
/** /**
* 如果token为本次请求新创建的则以此字符串为key存储在当前request中 * 常量key标记: 如果token为本次请求新创建的则以此字符串为key存储在当前request中
*/ */
public static final String JUST_CREATED_SAVE_KEY = "JUST_CREATED_SAVE_KEY_"; public static final String JUST_CREATED_SAVE_KEY = "JUST_CREATED_SAVE_KEY_";
/** /**
* 如果本次请求已经验证过[无操作过期], 则以此值存储在当前request中 TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY * 常量key标记: 如果本次请求已经验证过[无操作过期], 则以此值存储在当前request中
*/ */
public static final String TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY = "TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY_"; public static final String TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY = "TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY_";
/** /**
* 在登录时默认使用的设备名称 * 常量key标记: 在登录时默认使用的设备名称
*/ */
public static final String DEFAULT_LOGIN_DEVICE = "default-device"; public static final String DEFAULT_LOGIN_DEVICE = "default-device";
/** /**
* 在进行临时身份切换时使用的key * 常量key标记: 在进行临时身份切换时使用的key
*/ */
public static final String SWITCH_TO_SAVE_KEY = "SWITCH_TO_SAVE_KEY_"; public static final String SWITCH_TO_SAVE_KEY = "SWITCH_TO_SAVE_KEY_";
// =================== token-style 相关 ===================
/**
* token风格: uuid
*/
public static final String TOKEN_STYLE_UUID = "uuid";
/**
* token风格: 简单uuid (不带下划线)
*/
public static final String TOKEN_STYLE_SIMPLE_UUID = "simple-uuid";
/**
* token风格: 32位随机字符串
*/
public static final String TOKEN_STYLE_RANDOM_32 = "random-32";
/**
* token风格: 64位随机字符串
*/
public static final String TOKEN_STYLE_RANDOM_64 = "random-64";
/**
* token风格: 128位随机字符串
*/
public static final String TOKEN_STYLE_RANDOM_128 = "random-128";
/**
* token风格: tik风格 (2_14_16)
*/
public static final String TOKEN_STYLE_RANDOM_TIK = "tik";
} }

View File

@ -7,31 +7,28 @@ import java.util.List;
import java.util.Random; import java.util.Random;
/** /**
* sa-token 内部代码工具类 * sa-token 内部代码工具类
*
* @author kong * @author kong
* *
*/ */
public class SaTokenInsideUtil { public class SaTokenInsideUtil {
/** /**
* 打印 sa-token 版本字符画 * 打印 sa-token 版本字符画
*/ */
public static void printSaToken() { public static void printSaToken() {
String str = String str = "____ ____ ___ ____ _ _ ____ _ _ \r\n" + "[__ |__| __ | | | |_/ |___ |\\ | \r\n"
"____ ____ ___ ____ _ _ ____ _ _ \r\n" + + "___] | | | |__| | \\_ |___ | \\| \r\n" + "sa-token" + SaTokenConsts.VERSION_NO
"[__ |__| __ | | | |_/ |___ |\\ | \r\n" + + " \r\n" + "GitHub" + SaTokenConsts.GITHUB_URL; // + "\r\n";
"___] | | | |__| | \\_ |___ | \\| \r\n" +
"sa-token" + SaTokenConsts.VERSION_NO + " \r\n" +
"GitHub" + SaTokenConsts.GITHUB_URL; // + "\r\n";
System.out.println(str); System.out.println(str);
} }
/** /**
* 生成指定长度的随机字符串 * 生成指定长度的随机字符串
* @param length 字符串的长度 *
* @return 一个随机字符串 * @param length 字符串的长度
* @return 一个随机字符串
*/ */
public static String getRandomString(int length) { public static String getRandomString(int length) {
String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
@ -43,68 +40,69 @@ public class SaTokenInsideUtil {
} }
return sb.toString(); return sb.toString();
} }
/** /**
* 以当前时间戳和随机int数字拼接一个随机字符串 * 以当前时间戳和随机int数字拼接一个随机字符串
* @return 随机字符串 *
* @return 随机字符串
*/ */
public static String getMarking28() { public static String getMarking28() {
return System.currentTimeMillis() + "" + new Random().nextInt(Integer.MAX_VALUE); return System.currentTimeMillis() + "" + new Random().nextInt(Integer.MAX_VALUE);
} }
/** /**
* 从集合里查询数据 * 从集合里查询数据
* @param dataList 数据集合 *
* @param prefix 前缀 * @param dataList 数据集合
* @param keyword 关键字 * @param prefix 前缀
* @param start 起始位置 (-1代表查询所有) * @param keyword 关键字
* @param size 获取条数 * @param start 起始位置 (-1代表查询所有)
* @return 符合条件的新数据集合 * @param size 获取条数
* @return 符合条件的新数据集合
*/ */
public static List<String> searchList(Collection<String> dataList, String prefix, String keyword, int start, int size) { public static List<String> searchList(Collection<String> dataList, String prefix, String keyword, int start,
if(prefix == null) { int size) {
if (prefix == null) {
prefix = ""; prefix = "";
} }
if(keyword == null) { if (keyword == null) {
keyword = ""; keyword = "";
} }
// 挑选出所有符合条件的 // 挑选出所有符合条件的
List<String> list = new ArrayList<String>(); List<String> list = new ArrayList<String>();
Iterator<String> keys = dataList.iterator(); Iterator<String> keys = dataList.iterator();
while (keys.hasNext()) { while (keys.hasNext()) {
String key = keys.next(); String key = keys.next();
if(key.startsWith(prefix) && key.indexOf(keyword) > -1) { if (key.startsWith(prefix) && key.indexOf(keyword) > -1) {
list.add(key); list.add(key);
} }
} }
// 取指定段数据 // 取指定段数据
return searchList(list, start, size); return searchList(list, start, size);
} }
/** /**
* 从集合里查询数据 * 从集合里查询数据
* @param list 数据集合 *
* @param list 数据集合
* @param start 起始位置 (-1代表查询所有) * @param start 起始位置 (-1代表查询所有)
* @param size 获取条数 * @param size 获取条数
* @return 符合条件的新数据集合 * @return 符合条件的新数据集合
*/ */
public static List<String> searchList(List<String> list, int start, int size) { public static List<String> searchList(List<String> list, int start, int size) {
// 取指定段数据 // 取指定段数据
if(start < 0) { if (start < 0) {
return list; return list;
} }
int end = start + size; int end = start + size;
List<String> list2 = new ArrayList<String>(); List<String> list2 = new ArrayList<String>();
for (int i = start; i < end; i++) { for (int i = start; i < end; i++) {
if(i >= list.size()) { if (i >= list.size()) {
return list2; return list2;
} }
list2.add(list.get(i)); list2.add(list.get(i));
} }
return list2; return list2;
} }
} }

View File

@ -21,7 +21,10 @@ import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.util.SaTokenInsideUtil; import cn.dev33.satoken.util.SaTokenInsideUtil;
/** /**
* sa-token持久层的实现类, 基于redis (to jackson) * sa-token持久层的实现类, 基于redis (使用 jackson 序列化方式)
*
* @author kong
*
*/ */
@Component @Component
public class SaTokenDaoRedisJackson implements SaTokenDao { public class SaTokenDaoRedisJackson implements SaTokenDao {
@ -97,7 +100,8 @@ public class SaTokenDaoRedisJackson implements SaTokenDao {
@Override @Override
public void updateValue(String key, String value) { public void updateValue(String key, String value) {
long expire = getTimeout(key); long expire = getTimeout(key);
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) { // -2 = 无此键 // -2 = 无此键
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) {
return; return;
} }
this.setValue(key, value, expire); this.setValue(key, value, expire);
@ -167,7 +171,8 @@ public class SaTokenDaoRedisJackson implements SaTokenDao {
@Override @Override
public void updateSession(SaSession session) { public void updateSession(SaSession session) {
long expire = getSessionTimeout(session.getId()); long expire = getSessionTimeout(session.getId());
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) { // -2 = 无此键 // -2 = 无此键
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) {
return; return;
} }
this.saveSession(session, expire); this.saveSession(session, expire);

View File

@ -18,12 +18,15 @@ import cn.dev33.satoken.util.SaTokenInsideUtil;
/** /**
* sa-token持久层的实现类, 基于redis * sa-token持久层的实现类, 基于redis
*
* @author kong
*
*/ */
@Component @Component
public class SaTokenDaoRedis implements SaTokenDao { public class SaTokenDaoRedis implements SaTokenDao {
/** /**
* string专用 * string专用
*/ */
@Autowired @Autowired
public StringRedisTemplate stringRedisTemplate; public StringRedisTemplate stringRedisTemplate;
@ -52,7 +55,7 @@ public class SaTokenDaoRedis implements SaTokenDao {
/** /**
* 根据key获取value如果没有则返回空 * 根据key获取value如果没有则返回空
*/ */
@Override @Override
public String getValue(String key) { public String getValue(String key) {
@ -78,7 +81,8 @@ public class SaTokenDaoRedis implements SaTokenDao {
@Override @Override
public void updateValue(String key, String value) { public void updateValue(String key, String value) {
long expire = getTimeout(key); long expire = getTimeout(key);
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) { // -2 = 无此键 // -2 = 无此键
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) {
return; return;
} }
this.setValue(key, value, expire); this.setValue(key, value, expire);
@ -148,7 +152,8 @@ public class SaTokenDaoRedis implements SaTokenDao {
@Override @Override
public void updateSession(SaSession session) { public void updateSession(SaSession session) {
long expire = getSessionTimeout(session.getId()); long expire = getSessionTimeout(session.getId());
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) { // -2 = 无此键 // -2 = 无此键
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) {
return; return;
} }
this.saveSession(session, expire); this.saveSession(session, expire);

View File

@ -11,7 +11,8 @@ import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
/** /**
* sa-token 基于 Spring Aop 的注解鉴权 * sa-token 基于 Spring Aop 的注解鉴权
*
* @author kong * @author kong
*/ */
@Aspect @Aspect
@ -19,46 +20,46 @@ import cn.dev33.satoken.stp.StpUtil;
public class SaCheckAspect { public class SaCheckAspect {
/** /**
* *
*/ */
public SaCheckAspect() { public SaCheckAspect() {
} }
/** /**
* 获取本切面使用的StpLogic * 获取本切面使用的StpLogic
*/ */
public StpLogic getStpLogic() { public StpLogic getStpLogic() {
return StpUtil.stpLogic; return StpUtil.stpLogic;
} }
/** /**
* 定义AOP签名 (切入所有使用sa-token鉴权注解的方法) * 定义AOP签名 (切入所有使用sa-token鉴权注解的方法)
*/ */
public static final String POINTCUT_SIGN = "@within(cn.dev33.satoken.annotation.SaCheckLogin) || @annotation(cn.dev33.satoken.annotation.SaCheckLogin) || " public static final String POINTCUT_SIGN = "@within(cn.dev33.satoken.annotation.SaCheckLogin) || @annotation(cn.dev33.satoken.annotation.SaCheckLogin) || "
+ "@within(cn.dev33.satoken.annotation.SaCheckRole) || @annotation(cn.dev33.satoken.annotation.SaCheckRole) || " + "@within(cn.dev33.satoken.annotation.SaCheckRole) || @annotation(cn.dev33.satoken.annotation.SaCheckRole) || "
+ "@within(cn.dev33.satoken.annotation.SaCheckPermission) || @annotation(cn.dev33.satoken.annotation.SaCheckPermission)"; + "@within(cn.dev33.satoken.annotation.SaCheckPermission) || @annotation(cn.dev33.satoken.annotation.SaCheckPermission)";
/** /**
* 声明AOP签名 * 声明AOP签名
*/ */
@Pointcut(POINTCUT_SIGN) @Pointcut(POINTCUT_SIGN)
public void pointcut() { public void pointcut() {
} }
/** /**
* 环绕切入 * 环绕切入
*
* @param joinPoint 切面对象 * @param joinPoint 切面对象
* @return 底层方法执行后的返回值 * @return 底层方法执行后的返回值
* @throws Throwable 底层方法抛出的异常 * @throws Throwable 底层方法抛出的异常
*/ */
@Around("pointcut()") @Around("pointcut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable { public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
// 注解鉴权 // 注解鉴权
MethodSignature signature = (MethodSignature) joinPoint.getSignature(); MethodSignature signature = (MethodSignature) joinPoint.getSignature();
getStpLogic().checkMethodAnnotation(signature.getMethod()); getStpLogic().checkMethodAnnotation(signature.getMethod());
try { try {
// 执行原有逻辑 // 执行原有逻辑
Object obj = joinPoint.proceed(); Object obj = joinPoint.proceed();
return obj; return obj;
} catch (Throwable e) { } catch (Throwable e) {

View File

@ -16,102 +16,108 @@ import cn.dev33.satoken.spring.SaTokenServletSpringImpl;
import cn.dev33.satoken.stp.StpInterface; import cn.dev33.satoken.stp.StpInterface;
/** /**
* 利用spring的自动装配来加载开发者重写的Bean * 利用spring的自动装配来加载开发者重写的Bean
*
* @author kong * @author kong
* *
*/ */
@Component @Component
public class SaTokenSpringAutowired { public class SaTokenSpringAutowired {
/** /**
* 获取配置Bean * 获取配置Bean
* @return 配置对象 *
* @return 配置对象
*/ */
@Bean @Bean
@ConfigurationProperties(prefix="spring.sa-token") @ConfigurationProperties(prefix = "spring.sa-token")
public SaTokenConfig getSaTokenConfig() { public SaTokenConfig getSaTokenConfig() {
return new SaTokenConfig(); return new SaTokenConfig();
} }
/** /**
* 注入配置Bean * 注入配置Bean
*
* @param saTokenConfig 配置对象 * @param saTokenConfig 配置对象
*/ */
@Autowired @Autowired
public void setConfig(SaTokenConfig saTokenConfig){ public void setConfig(SaTokenConfig saTokenConfig) {
SaTokenManager.setConfig(saTokenConfig); SaTokenManager.setConfig(saTokenConfig);
} }
/** /**
* 注入持久化Bean * 注入持久化Bean
* @param saTokenDao . *
* @param saTokenDao SaTokenDao对象
*/ */
@Autowired(required = false) @Autowired(required = false)
public void setSaTokenDao(SaTokenDao saTokenDao){ public void setSaTokenDao(SaTokenDao saTokenDao) {
SaTokenManager.setSaTokenDao(saTokenDao); SaTokenManager.setSaTokenDao(saTokenDao);
} }
/** /**
* 注入权限认证Bean * 注入权限认证Bean
* @param stpInterface . *
* @param stpInterface StpInterface对象
*/ */
@Autowired(required = false) @Autowired(required = false)
public void setStpInterface(StpInterface stpInterface){ public void setStpInterface(StpInterface stpInterface) {
SaTokenManager.setStpInterface(stpInterface); SaTokenManager.setStpInterface(stpInterface);
} }
/** /**
* 注入Cookie操作Bean * 注入Cookie操作Bean
* @param saTokenCookie . *
* @param saTokenCookie SaTokenCookie对象
*/ */
@Autowired(required = false) @Autowired(required = false)
public void setSaTokenCookie(SaTokenCookie saTokenCookie){ public void setSaTokenCookie(SaTokenCookie saTokenCookie) {
SaTokenManager.setSaTokenCookie(saTokenCookie); SaTokenManager.setSaTokenCookie(saTokenCookie);
} }
/** /**
* 注入框架行为Bean * 注入框架行为Bean
* @param saTokenAction . *
* @param saTokenAction SaTokenAction对象
*/ */
@Autowired(required = false) @Autowired(required = false)
public void setSaTokenAction(SaTokenAction saTokenAction){ public void setSaTokenAction(SaTokenAction saTokenAction) {
SaTokenManager.setSaTokenAction(saTokenAction); SaTokenManager.setSaTokenAction(saTokenAction);
} }
/** /**
* 获取Servlet操作Bean (Spring版) * 获取Servlet操作Bean (Spring版)
* @return Servlet操作Bean (Spring版) *
* @return Servlet操作Bean (Spring版)
*/ */
@Bean @Bean
public SaTokenServlet getSaTokenServlet() { public SaTokenServlet getSaTokenServlet() {
return new SaTokenServletSpringImpl(); return new SaTokenServletSpringImpl();
} }
/**
* 注入Servlet操作Bean
* @param saTokenServlet .
*/
@Autowired
public void setSaTokenServlet(SaTokenServlet saTokenServlet){
SaTokenManager.setSaTokenServlet(saTokenServlet);
}
/** /**
* 路由匹配器 * 注入Servlet操作Bean
*
* @param saTokenServlet SaTokenServlet对象
*/
@Autowired
public void setSaTokenServlet(SaTokenServlet saTokenServlet) {
SaTokenManager.setSaTokenServlet(saTokenServlet);
}
/**
* 路由匹配器
*/ */
public static PathMatcher pathMatcher; public static PathMatcher pathMatcher;
/** /**
* 利用自动匹配特性获取SpringMVC框架内部使用的路由匹配器 * 利用自动匹配特性获取SpringMVC框架内部使用的路由匹配器
*
* @param pathMatcher 要设置的 pathMatcher * @param pathMatcher 要设置的 pathMatcher
*/ */
@Autowired(required = false) @Autowired(required = false)
public static void setPathMatcher(PathMatcher pathMatcher) { public static void setPathMatcher(PathMatcher pathMatcher) {
SaTokenSpringAutowired.pathMatcher = pathMatcher; SaTokenSpringAutowired.pathMatcher = pathMatcher;
} }
} }

View File

@ -12,29 +12,29 @@ import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
/** /**
* 注解式鉴权 - 拦截器 * 注解式鉴权 - 拦截器
*
* @author kong * @author kong
*/ */
public class SaAnnotationInterceptor implements HandlerInterceptor { public class SaAnnotationInterceptor implements HandlerInterceptor {
/** /**
* 底层 StpLogic 对象 * 在进行注解鉴权时使用 StpLogic 对象
*/ */
public StpLogic stpLogic = null; public StpLogic stpLogic = null;
/** /**
* @return 底层 StpLogic 对象 * @return 在进行注解鉴权时使用 StpLogic 对象
*/ */
public StpLogic getStpLogic() { public StpLogic getStpLogic() {
if(stpLogic == null) { if (stpLogic == null) {
stpLogic = StpUtil.stpLogic; stpLogic = StpUtil.stpLogic;
} }
return stpLogic; return stpLogic;
} }
/** /**
* @param stpLogic 底层 StpLogic 对象 * @param stpLogic 在进行注解鉴权时使用 StpLogic 对象
* @return 拦截器自身 * @return 拦截器自身
*/ */
public SaAnnotationInterceptor setStpLogic(StpLogic stpLogic) { public SaAnnotationInterceptor setStpLogic(StpLogic stpLogic) {
@ -42,33 +42,30 @@ public class SaAnnotationInterceptor implements HandlerInterceptor {
return this; return this;
} }
/** /**
* 创建并指定一个默认的 StpLogic * 构建 注解式鉴权 - 拦截器
*/ */
public SaAnnotationInterceptor() { public SaAnnotationInterceptor() {
} }
/** /**
* 每次请求之前触发的方法 * 每次请求之前触发的方法
*/ */
@Override @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception { throws Exception {
// 获取处理method // 获取处理method
if (handler instanceof HandlerMethod == false) { if (handler instanceof HandlerMethod == false) {
return true; return true;
} }
Method method = ((HandlerMethod) handler).getMethod(); Method method = ((HandlerMethod) handler).getMethod();
// 进行验证 // 进行验证
getStpLogic().checkMethodAnnotation(method); getStpLogic().checkMethodAnnotation(method);
// 通过验证 // 通过验证
return true; return true;
} }
} }

View File

@ -5,16 +5,18 @@ import javax.servlet.http.HttpServletResponse;
/** /**
* 执行验证方法的辅助类 * 执行验证方法的辅助类
*
* @author kong * @author kong
* *
*/ */
public interface SaRouteFunction { public interface SaRouteFunction {
/** /**
* 执行验证的方法 * 执行验证的方法
* @param request request对象 *
* @param response response对象 * @param request request对象
* @param handler 处理对象 * @param response response对象
* @param handler 处理对象
*/ */
public void run(HttpServletRequest request, HttpServletResponse response, Object handler); public void run(HttpServletRequest request, HttpServletResponse response, Object handler);

View File

@ -19,7 +19,7 @@ import cn.dev33.satoken.fun.SaFunction;
public class SaRouterUtil { public class SaRouterUtil {
/** /**
* 在进行路由匹配时所使用的 PathMatcher 对象 * 在进行路由匹配时所使用的 PathMatcher 对象
*/ */
private static PathMatcher pathMatcher; private static PathMatcher pathMatcher;

View File

@ -6,14 +6,15 @@ import javax.servlet.http.HttpServletResponse;
import cn.dev33.satoken.servlet.SaTokenServlet; import cn.dev33.satoken.servlet.SaTokenServlet;
/** /**
* sa-token 对cookie的相关操作 接口实现类 * sa-token 对cookie的相关操作 接口实现类
*
* @author kong * @author kong
* *
*/ */
public class SaTokenServletSpringImpl implements SaTokenServlet { public class SaTokenServletSpringImpl implements SaTokenServlet {
/** /**
* 获取当前请求的Request对象 * 获取当前请求的Request对象
*/ */
@Override @Override
public HttpServletRequest getRequest() { public HttpServletRequest getRequest() {
@ -21,11 +22,11 @@ public class SaTokenServletSpringImpl implements SaTokenServlet {
} }
/** /**
* 获取当前请求的Response对象 * 获取当前请求的Response对象
*/ */
@Override @Override
public HttpServletResponse getResponse() { public HttpServletResponse getResponse() {
return SpringMVCUtil.getResponse(); return SpringMVCUtil.getResponse();
} }
} }

View File

@ -6,6 +6,8 @@ import javax.servlet.http.HttpServletResponse;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.request.ServletRequestAttributes;
import cn.dev33.satoken.exception.SaTokenException;
/** /**
* SpringMVC相关操作 * SpringMVC相关操作
* @author kong * @author kong
@ -18,9 +20,9 @@ public class SpringMVCUtil {
* @return request * @return request
*/ */
public static HttpServletRequest getRequest() { public static HttpServletRequest getRequest() {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();// 大善人SpringMVC提供的封装 ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if(servletRequestAttributes == null) { if(servletRequestAttributes == null) {
throw new RuntimeException("当前环境非JavaWeb"); throw new SaTokenException("非Web上下文无法获取Request");
} }
return servletRequestAttributes.getRequest(); return servletRequestAttributes.getRequest();
} }
@ -30,9 +32,9 @@ public class SpringMVCUtil {
* @return response * @return response
*/ */
public static HttpServletResponse getResponse() { public static HttpServletResponse getResponse() {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();// 大善人SpringMVC提供的封装 ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if(servletRequestAttributes == null) { if(servletRequestAttributes == null) {
throw new RuntimeException("当前环境非JavaWeb"); throw new SaTokenException("非Web上下文无法获取Request");
} }
return servletRequestAttributes.getResponse(); return servletRequestAttributes.getResponse();
} }