提交 26ee628b 编写于 作者: shengzhang_'s avatar shengzhang_

完善源码注释

上级 03e38c54
......@@ -3,6 +3,7 @@ package cn.dev33.satoken.action;
import java.util.UUID;
import cn.dev33.satoken.SaTokenManager;
import cn.dev33.satoken.util.SaTokenConsts;
import cn.dev33.satoken.util.SaTokenInsideUtil;
/**
......@@ -21,30 +22,30 @@ public class SaTokenActionDefaultImpl implements SaTokenAction {
// 根据配置的tokenStyle生成不同风格的token
String tokenStyle = SaTokenManager.getConfig().getTokenStyle();
// uuid
if("uuid".equals(tokenStyle)) {
if(SaTokenConsts.TOKEN_STYLE_UUID.equals(tokenStyle)) {
return UUID.randomUUID().toString();
}
// 简单uuid (不带下划线)
if("simple-uuid".equals(tokenStyle)) {
if(SaTokenConsts.TOKEN_STYLE_SIMPLE_UUID.equals(tokenStyle)) {
return UUID.randomUUID().toString().replaceAll("-", "");
}
// 32位随机字符串
if("random-32".equals(tokenStyle)) {
if(SaTokenConsts.TOKEN_STYLE_RANDOM_32.equals(tokenStyle)) {
return SaTokenInsideUtil.getRandomString(32);
}
// 64位随机字符串
if("random-64".equals(tokenStyle)) {
if(SaTokenConsts.TOKEN_STYLE_RANDOM_64.equals(tokenStyle)) {
return SaTokenInsideUtil.getRandomString(64);
}
// 128位随机字符串
if("random-128".equals(tokenStyle)) {
if(SaTokenConsts.TOKEN_STYLE_RANDOM_128.equals(tokenStyle)) {
return SaTokenInsideUtil.getRandomString(128);
}
// 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) + "__";
}
// 默认,还是uuid
// 默认,还是uuid
return UUID.randomUUID().toString();
}
......
package cn.dev33.satoken.config;
/**
* sa-token 配置类 Model
* <p> 你可以通过yml、properties、java代码等形式配置本类参数,具体请查阅官方文档
* sa-token 配置类 Model
* <p>
* 你可以通过yml、properties、java代码等形式配置本类参数,具体请查阅官方文档: http://sa-token.dev33.cn/
*
* @author kong
*
*/
public class SaTokenConfig {
/** token名称 (同时也是cookie名称) */
private String tokenName = "satoken";
private String tokenName = "satoken";
/** token的长久有效期(单位:秒) 默认30天, -1代表永久 */
private long timeout = 30 * 24 * 60 * 60;
/** token临时有效期 [指定时间内无操作就视为token过期] (单位/秒), 默认-1 代表不限制 (例如可以设置为1800代表30分钟内无操作就过期) */
private long activityTimeout = -1;
/** 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) */
private Boolean allowConcurrentLogin = true;
/** 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) */
private Boolean isShare = true;
private long timeout = 30 * 24 * 60 * 60;
/**
* token临时有效期 [指定时间内无操作就视为token过期] (单位: 秒), 默认-1 代表不限制
* (例如可以设置为1800代表30分钟内无操作就过期)
*/
private long activityTimeout = -1;
/** 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录) */
private Boolean allowConcurrentLogin = true;
/** 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token) */
private Boolean isShare = true;
/** 是否尝试从请求体里读取token */
private Boolean isReadBody = true;
private Boolean isReadBody = true;
/** 是否尝试从header里读取token */
private Boolean isReadHead = true;
private Boolean isReadHead = true;
/** 是否尝试从cookie里读取token */
private Boolean isReadCookie = true;
private Boolean isReadCookie = true;
/** token风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) */
private String tokenStyle = "uuid";
private String tokenStyle = "uuid";
/** 默认dao层实现类中,每次清理过期数据间隔的时间 (单位: 秒) ,默认值30秒,设置为-1代表不启动定时清理 */
private int dataRefreshPeriod = 30;
/** 获取[token专属session]时是否必须登录 (如果配置为true,会在每次获取[token-session]时校验是否登录) */
private Boolean tokenSessionCheckLogin = true;
private Boolean tokenSessionCheckLogin = true;
/** 是否在初始化配置时打印版本字符画 */
private Boolean isV = true;
/**
* @return tokenName
* @return token名称 (同时也是cookie名称)
*/
public String getTokenName() {
return tokenName;
}
/**
* @param tokenName 要设置的 tokenName
* @param tokenName token名称 (同时也是cookie名称)
*/
public void setTokenName(String tokenName) {
this.tokenName = tokenName;
}
/**
* @return timeout
* @return token的长久有效期(单位:秒) 默认30天, -1代表永久
*/
public long getTimeout() {
return timeout;
}
/**
* @param timeout 要设置的 timeout
* @param timeout token的长久有效期(单位:秒) 默认30天, -1代表永久
*/
public void setTimeout(long timeout) {
this.timeout = timeout;
}
/**
* @return activityTimeout
* @return token临时有效期 [指定时间内无操作就视为token过期] (单位: 秒), 默认-1 代表不限制
* (例如可以设置为1800代表30分钟内无操作就过期)
*/
public long getActivityTimeout() {
return activityTimeout;
}
/**
* @param activityTimeout 要设置的 activityTimeout
* @param activityTimeout token临时有效期 [指定时间内无操作就视为token过期] (单位: 秒), 默认-1 代表不限制
* (例如可以设置为1800代表30分钟内无操作就过期)
*/
public void setActivityTimeout(long activityTimeout) {
this.activityTimeout = activityTimeout;
}
/**
* @return allowConcurrentLogin
* @return 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
*/
public Boolean getAllowConcurrentLogin() {
return allowConcurrentLogin;
}
/**
* @param allowConcurrentLogin 要设置的 allowConcurrentLogin
* @param allowConcurrentLogin 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
*/
public void setAllowConcurrentLogin(Boolean allowConcurrentLogin) {
this.allowConcurrentLogin = allowConcurrentLogin;
}
/**
* @return isShare
* @return 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
*/
public Boolean getIsShare() {
return isShare;
}
/**
* @param isShare 要设置的 isShare
* @param 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
*/
public void setIsShare(Boolean isShare) {
this.isShare = isShare;
}
/**
* @return isReadBody
* @return 是否尝试从请求体里读取token
*/
public Boolean getIsReadBody() {
return isReadBody;
}
/**
* @param isReadBody 要设置的 isReadBody
* @param isReadBody 是否尝试从请求体里读取token
*/
public void setIsReadBody(Boolean isReadBody) {
this.isReadBody = isReadBody;
}
/**
* @return isReadHead
* @return 是否尝试从header里读取token
*/
public Boolean getIsReadHead() {
return isReadHead;
}
/**
* @param isReadHead 要设置的 isReadHead
* @param 是否尝试从header里读取token
*/
public void setIsReadHead(Boolean isReadHead) {
this.isReadHead = isReadHead;
}
/**
* @return isReadCookie
* @return 是否尝试从cookie里读取token
*/
public Boolean getIsReadCookie() {
return isReadCookie;
}
/**
* @param isReadCookie 要设置的 isReadCookie
* @param 是否尝试从cookie里读取token
*/
public void setIsReadCookie(Boolean isReadCookie) {
this.isReadCookie = isReadCookie;
}
/**
* @return tokenStyle
* @return token风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik)
*/
public String getTokenStyle() {
return tokenStyle;
}
/**
* @param tokenStyle 要设置的 tokenStyle
* @param token风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik)
*/
public void setTokenStyle(String tokenStyle) {
this.tokenStyle = tokenStyle;
}
/**
* @return dataRefreshPeriod
* @return 默认dao层实现类中,每次清理过期数据间隔的时间 (单位: 秒) ,默认值30秒,设置为-1代表不启动定时清理
*/
public int getDataRefreshPeriod() {
return dataRefreshPeriod;
}
/**
* @param dataRefreshPeriod 要设置的 dataRefreshPeriod
* @param dataRefreshPeriod 默认dao层实现类中,每次清理过期数据间隔的时间 (单位: 秒)
* ,默认值30秒,设置为-1代表不启动定时清理
*/
public void setDataRefreshPeriod(int dataRefreshPeriod) {
this.dataRefreshPeriod = dataRefreshPeriod;
}
/**
* @return tokenSessionCheckLogin
* @return 获取[token专属session]时是否必须登录 (如果配置为true,会在每次获取[token-session]时校验是否登录)
*/
public Boolean getTokenSessionCheckLogin() {
return tokenSessionCheckLogin;
}
/**
* @param tokenSessionCheckLogin 要设置的 tokenSessionCheckLogin
* @param tokenSessionCheckLogin 获取[token专属session]时是否必须登录
* (如果配置为true,会在每次获取[token-session]时校验是否登录)
*/
public void setTokenSessionCheckLogin(Boolean tokenSessionCheckLogin) {
this.tokenSessionCheckLogin = tokenSessionCheckLogin;
}
/**
* @return isV
* @return 是否在初始化配置时打印版本字符画
*/
public Boolean getIsV() {
return isV;
}
/**
* @param isV 要设置的 isV
* @param isV 是否在初始化配置时打印版本字符画
*/
public void setIsV(Boolean isV) {
this.isV = isV;
}
@Override
public String toString() {
return "SaTokenConfig [tokenName=" + tokenName + ", timeout=" + timeout + ", activityTimeout=" + activityTimeout
......@@ -224,22 +230,4 @@ public class SaTokenConfig {
+ tokenSessionCheckLogin + ", isV=" + isV + "]";
}
}
......@@ -8,44 +8,46 @@ import java.util.Map;
import java.util.Properties;
/**
* sa-token配置文件创建工厂类
* sa-token配置文件的构建工厂类
* <p>
* 只有在非IOC环境下才会用到此类
*
* @author kong
*
*/
public class SaTokenConfigFactory {
/**
* 默认配置文件地址
* 配置文件地址
*/
public static String configPath = "sa-token.properties";
/**
* 根据指定路径获取配置信息
* @return 一个SaTokenConfig对象
* 根据configPath路径获取配置信息
*
* @return 一个SaTokenConfig对象
*/
public static SaTokenConfig createConfig() {
Map<String, String> map = readPropToMap(configPath);
if(map == null){
if (map == null) {
// throw new RuntimeException("找不到配置文件:" + configPath, null);
}
return (SaTokenConfig)initPropByMap(map, new SaTokenConfig());
return (SaTokenConfig) initPropByMap(map, new SaTokenConfig());
}
/**
* 将指定路径的properties配置文件读取到Map中
* 工具方法: 将指定路径的properties配置文件读取到Map中
*
* @param propertiesPath 配置文件地址
* @return 一个Map
*/
private static Map<String, String> readPropToMap(String propertiesPath){
Map<String, String> map = new HashMap<String, String>();
private static Map<String, String> readPropToMap(String propertiesPath) {
Map<String, String> map = new HashMap<String, String>(16);
try {
InputStream is = SaTokenConfigFactory.class.getClassLoader().getResourceAsStream(propertiesPath);
if(is == null){
return null;
}
InputStream is = SaTokenConfigFactory.class.getClassLoader().getResourceAsStream(propertiesPath);
if (is == null) {
return null;
}
Properties prop = new Properties();
prop.load(is);
for (String key : prop.stringPropertyNames()) {
......@@ -55,38 +57,41 @@ public class SaTokenConfigFactory {
throw new RuntimeException("配置文件(" + propertiesPath + ")加载失败", e);
}
return map;
}
/**
* 将 Map 的值映射到 Model 上
* @param map 属性集合
* @param obj 对象,或类型
* @return 返回实例化后的对象
*/
private static Object initPropByMap(Map<String, String> map, Object obj){
if(map == null){
map = new HashMap<String, String>();
}
// 1、取出类型
Class<?> cs = null;
if(obj instanceof Class){ // 如果是一个类型,则将obj=null,以便完成静态属性反射赋值
cs = (Class<?>)obj;
obj = null;
}else{ // 如果是一个对象,则取出其类型
cs = obj.getClass();
}
// 2、遍历类型属性,反射赋值
for (Field field : cs.getDeclaredFields()) {
}
/**
* 工具方法: 将 Map 的值映射到一个 Model 上
*
* @param map 属性集合
* @param obj 对象, 或类型
* @return 返回实例化后的对象
*/
private static Object initPropByMap(Map<String, String> map, Object obj) {
if (map == null) {
map = new HashMap<String, String>(16);
}
// 1、取出类型
Class<?> cs = null;
if (obj instanceof Class) {
// 如果是一个类型,则将obj=null,以便完成静态属性反射赋值
cs = (Class<?>) obj;
obj = null;
} else {
// 如果是一个对象,则取出其类型
cs = obj.getClass();
}
// 2、遍历类型属性,反射赋值
for (Field field : cs.getDeclaredFields()) {
String value = map.get(field.getName());
if (value == null) {
continue; // 如果为空代表没有配置此项
// 如果为空代表没有配置此项
continue;
}
try {
Object valueConvert = getObjectByClass(value, field.getType()); // 转换值类型
Object valueConvert = getObjectByClass(value, field.getType());
field.setAccessible(true);
field.set(obj, valueConvert);
} catch (IllegalArgumentException e) {
......@@ -95,41 +100,39 @@ public class SaTokenConfigFactory {
throw new RuntimeException("属性赋值出错:" + field.getName(), e);
}
}
return obj;
}
/**
* 将字符串转化为指定数据类型
* @param str 值
* @param cs 要转换的类型
* @return 转化好的结果
*/
return obj;
}
/**
* 工具方法: 将字符串转化为指定数据类型
*
* @param str 值
* @param cs 要转换的类型
* @return 转化好的结果
*/
@SuppressWarnings("unchecked")
private static <T>T getObjectByClass(String str, Class<T> cs){
private static <T> T getObjectByClass(String str, Class<T> cs) {
Object value = null;
if(str == null){
if (str == null) {
value = null;
}else if (cs.equals(String.class)) {
} else if (cs.equals(String.class)) {
value = str;
} else if (cs.equals(int.class)||cs.equals(Integer.class)) {
} 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{
} 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;
}
return (T) value;
}
}
......@@ -5,7 +5,8 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* sa-token 对cookie的相关操作 接口类
* sa-token 对cookie的相关操作 接口类
*
* @author kong
*
*/
......@@ -13,36 +14,40 @@ public interface SaTokenCookie {
/**
* 在request对象中获取指定Cookie
* @param request request对象
* @param cookieName Cookie名称
*
* @param request request对象
* @param cookieName Cookie名称
* @return 查找到的Cookie对象
*/
public Cookie getCookie(HttpServletRequest request, String cookieName);
/**
* 添加Cookie
* @param response response对象
* @param name Cookie名称
* @param value Cookie值
* @param path Cookie路径
*
* @param response response对象
* @param name Cookie名称
* @param value Cookie值
* @param path Cookie路径
* @param timeout 过期时间 (秒)
*/
public void addCookie(HttpServletResponse response, String name, String value, String path, int timeout);
/**
* 删除Cookie
* @param request request对象
* @param response response对象
*
* @param request request对象
* @param response response对象
* @param name Cookie名称
*/
public void delCookie(HttpServletRequest request, HttpServletResponse response, String name);
/**
* 修改Cookie的value值
* @param request request对象
*
* @param request request对象
* @param response response对象
* @param name Cookie名称
* @param value Cookie值
* @param name Cookie名称
* @param value Cookie值
*/
public void updateCookie(HttpServletRequest request, HttpServletResponse response, String name, String value);
......
......@@ -5,14 +5,15 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* sa-token 对cookie的相关操作 接口实现类
* sa-token 对cookie的相关操作 接口实现类
*
* @author kong
*
*/
public class SaTokenCookieDefaultImpl implements SaTokenCookie {
/**
* 获取指定cookie
* 获取指定cookie
*/
@Override
public Cookie getCookie(HttpServletRequest request, String cookieName) {
......@@ -20,7 +21,7 @@ public class SaTokenCookieDefaultImpl implements SaTokenCookie {
}
/**
* 添加cookie
* 添加cookie
*/
@Override
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
public void delCookie(HttpServletRequest request, HttpServletResponse response, String name) {
......@@ -36,7 +37,7 @@ public class SaTokenCookieDefaultImpl implements SaTokenCookie {
}
/**
* 修改cookie的value值
* 修改cookie的value值
*/
@Override
public void updateCookie(HttpServletRequest request, HttpServletResponse response, String name, String value) {
......
......@@ -5,15 +5,17 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Cookie操作工具类
* @author kong
* Cookie操作工具类
*
* @author kong
*/
public class SaTokenCookieUtil {
/**
* 在request对象中获取指定Cookie
* @param request request对象
* @param cookieName Cookie名称
*
* @param request request对象
* @param cookieName Cookie名称
* @return 查找到的Cookie对象
*/
public static Cookie getCookie(HttpServletRequest request, String cookieName) {
......@@ -30,11 +32,12 @@ public class SaTokenCookieUtil {
/**
* 添加cookie
*
* @param response response
* @param name Cookie名称
* @param name Cookie名称
* @param value Cookie值
* @param path Cookie写入路径
* @param timeout Cookie有效期 (秒)
* @param timeout Cookie有效期 (秒)
*/
public static void addCookie(HttpServletResponse response, String name, String value, String path, int timeout) {
Cookie cookie = new Cookie(name, value);
......@@ -48,9 +51,10 @@ public class SaTokenCookieUtil {
/**
* 删除Cookie
*
* @param request request对象
* @param response response对象
* @param name Cookie名称
* @param name Cookie名称
*/
public static void delCookie(HttpServletRequest request, HttpServletResponse response, String name) {
Cookie[] cookies = request.getCookies();
......@@ -66,10 +70,11 @@ public class SaTokenCookieUtil {
/**
* 修改cookie的value值
* @param request request对象
* @param response response对象
* @param name Cookie名称
* @param value Cookie值
*
* @param request request对象
* @param response response对象
* @param name Cookie名称
* @param value Cookie值
*/
public static void updateCookie(HttpServletRequest request, HttpServletResponse response, String name,
String value) {
......
......@@ -22,7 +22,7 @@ public class SaTokenDaoDefaultImpl implements SaTokenDao {
/**
* 所有数据集合
* 数据集合
*/
public Map<String, Object> dataMap = new ConcurrentHashMap<String, Object>();
......
......@@ -10,7 +10,7 @@ import java.util.List;
public class NotLoginException extends RuntimeException {
/**
*
* 序列化版本号
*/
private static final long serialVersionUID = 6806129545290130142L;
......@@ -56,6 +56,7 @@ public class NotLoginException extends RuntimeException {
* 异常类型
*/
private String type;
/**
* 获取异常类型
* @return 异常类型
......@@ -69,6 +70,7 @@ public class NotLoginException extends RuntimeException {
* loginKey
*/
private String loginKey;
/**
* 获得loginKey
* @return loginKey
......@@ -78,8 +80,6 @@ public class NotLoginException extends RuntimeException {
}
/**
* 构造方法创建一个
* @param message 异常消息
......@@ -87,7 +87,6 @@ public class NotLoginException extends RuntimeException {
* @param type 类型
*/
public NotLoginException(String message, String loginKey, String type) {
// 这里到底要不要拼接上login_key呢?纠结
super(message);
this.loginKey = loginKey;
this.type = type;
......@@ -101,19 +100,19 @@ public class NotLoginException extends RuntimeException {
*/
public static NotLoginException newInstance(String loginKey, String type) {
String message = null;
if(type.equals(NOT_TOKEN)) {
if(NOT_TOKEN.equals(type)) {
message = NOT_TOKEN_MESSAGE;
}
else if(type.equals(INVALID_TOKEN)) {
else if(INVALID_TOKEN.equals(type)) {
message = INVALID_TOKEN_MESSAGE;
}
else if(type.equals(TOKEN_TIMEOUT)) {
else if(TOKEN_TIMEOUT.equals(type)) {
message = TOKEN_TIMEOUT_MESSAGE;
}
else if(type.equals(BE_REPLACED)) {
else if(BE_REPLACED.equals(type)) {
message = BE_REPLACED_MESSAGE;
}
else if(type.equals(KICK_OUT)) {
else if(KICK_OUT.equals(type)) {
message = KICK_OUT_MESSAGE;
}
else {
......
......@@ -4,48 +4,49 @@ import cn.dev33.satoken.stp.StpUtil;
/**
* 没有指定权限码,抛出的异常
*
* @author kong
*
*/
public class NotPermissionException extends RuntimeException {
/**
*
* 序列化版本号
*/
private static final long serialVersionUID = 6806129545290130142L;
/** 权限码 */
private String code;
/**
* @return 获得权限码
* @return 获得权限码
*/
public String getCode() {
return code;
}
/**
* loginKey
* loginKey
*/
private String loginKey;
/**
* 获得loginKey
* @return loginKey
/**
* 获得loginKey
*
* @return loginKey
*/
public String getLoginKey() {
return loginKey;
}
public NotPermissionException(String code) {
this(code, StpUtil.stpLogic.loginKey);
}
public NotPermissionException(String code, String loginKey) {
// 这里到底要不要拼接上loginKey呢?纠结
super("无此权限:" + code);
this.code = code;
this.loginKey = loginKey;
}
this(code, StpUtil.stpLogic.loginKey);
}
public NotPermissionException(String code, String loginKey) {
super("无此权限:" + code);
this.code = code;
this.loginKey = loginKey;
}
}
......@@ -4,48 +4,50 @@ import cn.dev33.satoken.stp.StpUtil;
/**
* 没有指定角色标识,抛出的异常
*
* @author kong
*
*/
public class NotRoleException extends RuntimeException {
/**
*
* 序列化版本号
*/
private static final long serialVersionUID = 8243974276159004739L;
/** 角色标识 */
private String role;
/**
* @return 获得角色标识
* @return 获得角色标识
*/
public String getRole() {
return role;
}
/**
* loginKey
* loginKey
*/
private String loginKey;
/**
* 获得loginKey
* @return loginKey
/**
* 获得loginKey
*
* @return loginKey
*/
public String getLoginKey() {
return loginKey;
}
public NotRoleException(String role) {
this(role, StpUtil.stpLogic.loginKey);
}
this(role, StpUtil.stpLogic.loginKey);
}
public NotRoleException(String role, String loginKey) {
// 这里到底要不要拼接上loginKey呢?纠结
super("无此角色:" + role);
this.role = role;
this.loginKey = loginKey;
}
super("无此角色:" + role);
this.role = role;
this.loginKey = loginKey;
}
}
package cn.dev33.satoken.exception;
/**
* sa-token框架内部逻辑发生错误抛出的异常
* sa-token框架内部逻辑发生错误抛出的异常 (自定义此异常可方便开发者在做全局异常处理时分辨异常类型)
*
* @author kong
*
*/
public class SaTokenException extends RuntimeException {
/**
*
* 序列化版本号
*/
private static final long serialVersionUID = 6806129545290130132L;
/**
* 构建一个异常
* @param message 异常描述信息
* 构建一个异常
*
* @param message 异常描述信息
*/
public SaTokenException(String message) {
super(message);
}
super(message);
}
/**
* 构建一个异常
* @param cause 异常对象
* 构建一个异常
*
* @param cause 异常对象
*/
public SaTokenException(Throwable cause) {
super(cause);
}
super(cause);
}
}
package cn.dev33.satoken.fun;
/**
* 根据boolean变量,决定是否执行一个函数
* 根据boolean变量,决定是否执行一个函数
*
* @author kong
*
*/
public class IsRunFunction {
/**
* 变量
* 变量
*/
public Boolean isRun;
public final Boolean isRun;
/**
* 设定一个变量,如果为true,则执行exe函数
* 设定一个变量,如果为true,则执行exe函数
*
* @param isRun 变量
*/
public IsRunFunction(boolean isRun) {
this.isRun = isRun;
}
/**
* 根据变量决定是否执行此函数
* @param function 函数
* 根据变量决定是否执行此函数
*
* @param function 函数
*/
public void exe(SaFunction function) {
if(isRun) {
if (isRun) {
function.run();
}
}
}
package cn.dev33.satoken.fun;
/**
* 模拟身份方法的辅助类
* 设定一个函数,方便在Lambda表达式下的函数式编程
*
* @author kong
*
*/
public interface SaFunction {
/**
* 执行的方法
* 执行的方法
*/
public void run();
......
......@@ -4,24 +4,25 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet相关操作
* Servlet相关操作接口
*
* @author kong
*
*/
public interface SaTokenServlet {
/**
* 获取当前请求的 Request 对象
* 获取当前请求的 Request 对象
*
* @return 当前请求的Request对象
*/
public HttpServletRequest getRequest();
/**
* 获取当前请求的 Response 对象
* 获取当前请求的 Response 对象
*
* @return 当前请求的response对象
*/
public HttpServletResponse getResponse();
}
......@@ -3,28 +3,30 @@ package cn.dev33.satoken.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.dev33.satoken.exception.SaTokenException;
/**
* sa-token 对SaTokenServlet接口默认实现类
* sa-token 对SaTokenServlet接口默认实现类
*
* @author kong
*
*/
public class SaTokenServletDefaultImpl implements SaTokenServlet {
/**
* 获取当前请求的Request对象
* 获取当前请求的Request对象
*/
@Override
public HttpServletRequest getRequest() {
throw new RuntimeException("请实现SaTokenServlet接口后进行Servlet相关操作");
throw new SaTokenException("请实现SaTokenServlet接口后进行Servlet相关操作");
}
/**
* 获取当前请求的Response对象
* 获取当前请求的Response对象
*/
@Override
public HttpServletResponse getResponse() {
throw new RuntimeException("请实现SaTokenServlet接口后进行Servlet相关操作");
throw new SaTokenException("请实现SaTokenServlet接口后进行Servlet相关操作");
}
}
......@@ -9,213 +9,222 @@ import java.util.concurrent.ConcurrentHashMap;
import cn.dev33.satoken.SaTokenManager;
/**
* session会话
* Session Model
*
* @author kong
*
*/
public class SaSession implements Serializable {
private static final long serialVersionUID = 1L;
/** 此会话的id */
private String id;
/** 此会话的创建时间 */
/** 此Session的id */
private String id;
/** 此Session的创建时间 */
private long createTime;
/** 此会话的所有数据 */
/** 此Session的所有挂载数据 */
private Map<String, Object> dataMap = new ConcurrentHashMap<String, Object>();
/**
* 构建一个 session对象
* 构建一个Session对象
*/
public SaSession() {}
public SaSession() {
}
/**
* 构建一个 session对象
* @param id session的id
* 构建一个Session对象
*
* @param id Session的id
*/
public SaSession(String id) {
public SaSession(String id) {
this.id = id;
this.createTime = System.currentTimeMillis();
this.createTime = System.currentTimeMillis();
}
/**
* 获取此会话id
* @return 此会话的id
*/
/**
* 获取此会话id
*
* @return 此会话的id
*/
public String getId() {
return id;
}
/**
* 返回当前会话创建时间
* 返回当前会话创建时间
*
* @return 时间戳
*/
public long getCreateTime() {
return createTime;
}
// ----------------------- tokenSign相关
// ----------------------- TokenSign相关
/**
* 本session绑定的token签名列表
* 此Session绑定的token签名列表
*/
private List<TokenSign> tokenSignList = new Vector<TokenSign>();
/**
* 返回token签名列表
* 返回token签名列表的拷贝副本
*
* @return token签名列表
*/
public List<TokenSign> getTokenSignList() {
return new Vector<>(tokenSignList);
}
/**
* 查找一个token签名
* @param tokenValue token值
* 查找一个token签名
*
* @param tokenValue token值
* @return 查找到的tokenSign
*/
public TokenSign getTokenSign(String tokenValue) {
for (TokenSign tokenSign : getTokenSignList()) {
if(tokenSign.getValue().equals(tokenValue)){
return tokenSign;
}
if (tokenSign.getValue().equals(tokenValue)) {
return tokenSign;
}
}
return null;
}
/**
* 添加一个token签名
*
* @param tokenSign token签名
*/
public void addTokenSign(TokenSign tokenSign) {
// 如果已经存在于列表中,则无需再次添加
// 如果已经存在于列表中,则无需再次添加
for (TokenSign tokenSign2 : getTokenSignList()) {
if(tokenSign2.getValue().equals(tokenSign.getValue())){
return;
}
if (tokenSign2.getValue().equals(tokenSign.getValue())) {
return;
}
}
// 添加并更新
// 添加并更新
tokenSignList.add(tokenSign);
update();
}
/**
* 移除一个token签名
* @param tokenValue token名称
*
* @param tokenValue token名称
*/
public void removeTokenSign(String tokenValue) {
TokenSign tokenSign = getTokenSign(tokenValue);
if(tokenSignList.remove(tokenSign)) {
if (tokenSignList.remove(tokenSign)) {
update();
}
}
// ----------------------- 存取值
// ----------------------- 存取值
/**
* 写入一个值
* @param key 名称
* @param value 值
* 写入一个值
*
* @param key 名称
* @param value 值
*/
public void setAttribute(String key, Object value) {
dataMap.put(key, value);
update();
}
/**
* 取出一个值
* 取出一个值
*
* @param key 名称
* @return 值
* @return 值
*/
public Object getAttribute(String key) {
return dataMap.get(key);
}
/**
* 取值,并指定取不到值时的默认值
* @param key 名称
* @param defaultValue 取不到值的时候返回的默认值
* 取值,并指定取不到值时的默认值
*
* @param key 名称
* @param defaultValue 取不到值的时候返回的默认值
* @return value
*/
public Object getAttribute(String key, Object defaultValue) {
Object value = getAttribute(key);
if(value != null) {
if (value != null) {
return value;
}
return defaultValue;
}
/**
* 移除一个值
* 移除一个值
*
* @param key 要移除的值的名字
*/
public void removeAttribute(String key) {
dataMap.remove(key);
update();
}
/**
* 清空所有值
* 清空所有值
*/
public void clearAttribute() {
dataMap.clear();
update();
}
/**
* 是否含有指定key
* @param key 是否含有指定值
* @return 是否含有
* 是否含有指定key
*
* @param key 是否含有指定值
* @return 是否含有
*/
public boolean containsAttribute(String key) {
public boolean containsAttribute(String key) {
return dataMap.keySet().contains(key);
}
/**
* 返回当前session会话所有key
* @return 所有值的key列表
* 返回当前session会话所有key
*
* @return 所有值的key列表
*/
public Set<String> attributeKeys() {
return dataMap.keySet();
}
/**
* 获取数据集合(如果更新map里的值,请调用session.update()方法避免数据过时 )
* @return 返回底层储存值的map对象
* 获取数据挂载集合(如果更新map里的值,请调用session.update()方法避免产生脏数据 )
*
* @return 返回底层储存值的map对象
*/
public Map<String, Object> getDataMap() {
return dataMap;
}
// ----------------------- 一些操作
// ----------------------- 一些操作
/**
* 将这个session从持久库更新一下
* 将这个Session从持久库更新一下
*/
public void update() {
SaTokenManager.getSaTokenDao().updateSession(this);
}
/** 注销会话(注销后,此session会话将不再存储服务器上) */
/** 注销会话 (注销后,此session会话将不再存储服务器上) */
public void logout() {
SaTokenManager.getSaTokenDao().deleteSession(this.id);
}
/** 如果这个token的tokenSign数量为零,则直接注销会话 */
/** 当Session上的tokenSign数量为零时,注销会话 */
public void logoutByTokenSignCountToZero() {
if(tokenSignList.size() == 0) {
if (tokenSignList.size() == 0) {
logout();
}
}
}
......@@ -3,68 +3,71 @@ package cn.dev33.satoken.session;
import cn.dev33.satoken.SaTokenManager;
/**
* 自定义sa-session工具类
* 自定义Session工具类
*
* @author kong
*
*/
public class SaSessionCustomUtil {
/**
* 添加上指定前缀,防止恶意伪造session
* 添加上指定前缀,防止恶意伪造session
*/
public static String sessionKey = "custom";
/**
* 组织一下自定义session的id
* 组织一下自定义Session的id
*
* @param sessionId 会话id
* @return sessionId
*/
public static String getSessionKey(String sessionId) {
return SaTokenManager.getConfig().getTokenName() + ":" + sessionKey + ":session:" + sessionId;
}
/**
* 指定key的session是否存在
/**
* 验证指定key的Session是否存在
*
* @param sessionId session的id
* @return 是否存在
* @return 是否存在
*/
public boolean isExists(String sessionId) {
return SaTokenManager.getSaTokenDao().getSession(getSessionKey(sessionId)) != null;
}
/**
* 获取指定key的session
/**
* 获取指定key的Session
*
* @param sessionId key
* @param isCreate 如果没有,是否新建并返回
* @param isCreate 如果此Session尚未在DB创建,是否新建并返回
* @return SaSession
*/
public static SaSession getSessionById(String sessionId, boolean isCreate) {
SaSession session = SaTokenManager.getSaTokenDao().getSession(getSessionKey(sessionId));
if(session == null && isCreate) {
if (session == null && isCreate) {
session = new SaSession(getSessionKey(sessionId));
SaTokenManager.getSaTokenDao().saveSession(session, SaTokenManager.getConfig().getTimeout());
}
return session;
}
/**
* 获取指定key的session, 如果没有则新建并返回
/**
* 获取指定key的Session, 如果此Session尚未在DB创建,则新建并返回
*
* @param sessionId key
* @return session对象
* @return session对象
*/
public static SaSession getSessionById(String sessionId) {
return getSessionById(sessionId, true);
}
/**
* 删除指定key的session
* @param sessionId 删除指定key
/**
* 删除指定key的session
*
* @param sessionId 指定key
*/
public static void deleteSessionById(String sessionId) {
SaTokenManager.getSaTokenDao().deleteSession(getSessionKey(sessionId));
}
}
......@@ -3,66 +3,62 @@ package cn.dev33.satoken.session;
import java.io.Serializable;
/**
* 挂在到SaSession上的token签名
* token签名 Model
*
* 挂在到SaSession上的token签名
*
* @author kong
*
*/
public class TokenSign implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1406115065849845073L;
/**
* token值
* token值
*/
private String value;
/**
* 所在设备标识
* 所在设备标识
*/
private String device;
/** 构建一个 */
public TokenSign() {}
public TokenSign() {
}
/**
* 构建一个
* @param value token值
* @param device 所在设备标识
* 构建一个
*
* @param value token值
* @param device 所在设备标识
*/
public TokenSign(String value, String device) {
this.value = value;
this.device = device;
this.value = value;
this.device = device;
}
/**
* @return value
* @return token value
*/
public String getValue() {
return value;
}
/**
* @return device
* @return token登录设备
*/
public String getDevice() {
return device;
}
@Override
public String toString() {
return "TokenSign [value=" + value + ", device=" + device + "]";
}
}
package cn.dev33.satoken.stp;
/**
* 用来描述一个token常用信息的类
* token信息Model: 用来描述一个token的常用参数
*
* @author kong
*
*/
......@@ -13,177 +14,173 @@ public class SaTokenInfo {
/** token值 */
public String tokenValue;
/** 当前是否已经登录 */
/** 此token是否已经登录 */
public Boolean isLogin;
/** 当前loginId,未登录时为null */
/** 此token对应的LoginId,未登录时为null */
public Object loginId;
/** 当前loginKey */
/** LoginKey账号体系标识 */
public String loginKey;
/** token剩余有效期 (单位: 秒) */
public long tokenTimeout;
/** session剩余有效时间 (单位: 秒) */
/** User-Session剩余有效时间 (单位: 秒) */
public long sessionTimeout;
/** token专属session剩余有效时间 (单位: 秒) */
/** Token-Session剩余有效时间 (单位: 秒) */
public long tokenSessionTimeout;
/**
* token剩余无操作有效时间
*/
/** token剩余无操作有效时间 (单位: 秒) */
public long tokenActivityTimeout;
/** 当前登录设备 */
/** 登录设备标识 */
public String loginDevice;
/**
* @return tokenName
* @return token名称
*/
public String getTokenName() {
return tokenName;
}
/**
* @param tokenName 要设置的 tokenName
* @param tokenName token名称
*/
public void setTokenName(String tokenName) {
this.tokenName = tokenName;
}
/**
* @return tokenValue
* @return token
*/
public String getTokenValue() {
return tokenValue;
}
/**
* @param tokenValue 要设置的 tokenValue
* @param tokenValue token值
*/
public void setTokenValue(String tokenValue) {
this.tokenValue = tokenValue;
}
/**
* @return isLogin
* @return 此token是否已经登录
*/
public Boolean getIsLogin() {
return isLogin;
}
/**
* @param isLogin 要设置的 isLogin
* @param isLogin 此token是否已经登录
*/
public void setIsLogin(Boolean isLogin) {
this.isLogin = isLogin;
}
/**
* @return loginId
* @return 此token对应的LoginId,未登录时为null
*/
public Object getLoginId() {
return loginId;
}
/**
* @param loginId 要设置的 loginId
* @param loginId 此token对应的LoginId,未登录时为null
*/
public void setLoginId(Object loginId) {
this.loginId = loginId;
}
/**
* @return loginKey
* @return LoginKey账号体系标识
*/
public String getLoginKey() {
return loginKey;
}
/**
* @param loginKey 要设置的 loginKey
* @param loginKey LoginKey账号体系标识
*/
public void setLoginKey(String loginKey) {
this.loginKey = loginKey;
}
/**
* @return tokenTimeout
* @return token剩余有效期 (单位: 秒)
*/
public long getTokenTimeout() {
return tokenTimeout;
}
/**
* @param tokenTimeout 要设置的 tokenTimeout
* @param tokenTimeout token剩余有效期 (单位: 秒)
*/
public void setTokenTimeout(long tokenTimeout) {
this.tokenTimeout = tokenTimeout;
}
/**
* @return sessionTimeout
* @return User-Session剩余有效时间 (单位: 秒)
*/
public long getSessionTimeout() {
return sessionTimeout;
}
/**
* @param sessionTimeout 要设置的 sessionTimeout
* @param sessionTimeout User-Session剩余有效时间 (单位: 秒)
*/
public void setSessionTimeout(long sessionTimeout) {
this.sessionTimeout = sessionTimeout;
}
/**
* @return tokenSessionTimeout
* @return Token-Session剩余有效时间 (单位: 秒)
*/
public long getTokenSessionTimeout() {
return tokenSessionTimeout;
}
/**
* @param tokenSessionTimeout 要设置的 tokenSessionTimeout
* @param tokenSessionTimeout Token-Session剩余有效时间 (单位: 秒)
*/
public void setTokenSessionTimeout(long tokenSessionTimeout) {
this.tokenSessionTimeout = tokenSessionTimeout;
}
/**
* @return tokenActivityTimeout
* @return token剩余无操作有效时间 (单位: 秒)
*/
public long getTokenActivityTimeout() {
return tokenActivityTimeout;
}
/**
* @param tokenActivityTimeout 要设置的 tokenActivityTimeout
* @param tokenActivityTimeout token剩余无操作有效时间 (单位: 秒)
*/
public void setTokenActivityTimeout(long tokenActivityTimeout) {
this.tokenActivityTimeout = tokenActivityTimeout;
}
/**
* @return loginDevice
* @return 登录设备标识
*/
public String getLoginDevice() {
return loginDevice;
}
/**
* @param loginDevice 要设置的 loginDevice
* @param loginDevice 登录设备标识
*/
public void setLoginDevice(String loginDevice) {
this.loginDevice = loginDevice;
}
/**
* toString
*/
@Override
public String toString() {
return "SaTokenInfo [tokenName=" + tokenName + ", tokenValue=" + tokenValue + ", isLogin=" + isLogin
......@@ -191,18 +188,5 @@ public class SaTokenInfo {
+ ", sessionTimeout=" + sessionTimeout + ", tokenSessionTimeout=" + tokenSessionTimeout
+ ", tokenActivityTimeout=" + tokenActivityTimeout + ", loginDevice=" + loginDevice + "]";
}
}
......@@ -3,26 +3,28 @@ package cn.dev33.satoken.stp;
import java.util.List;
/**
* 开放权限验证接口,方便重写
* 权限认证接口,实现此接口即可集成权限认证功能
*
* @author kong
*/
public interface StpInterface {
/**
* 返回指定loginId所拥有的权限码集合
* @param loginId 账号id
* @param loginKey 具体的stp标识
* @return 该账号id具有的权限码集合
* 返回指定 LoginId 所拥有的权限码集合
*
* @param loginId 账号id
* @param loginKey 账号体系标识
* @return 该账号id具有的权限码集合
*/
public List<String> getPermissionList(Object loginId, String loginKey);
/**
* 返回指定loginId所拥有的角色标识集合
* @param loginId 账号id
* @param loginKey 具体的stp标识
* @return 该账号id具有的角色标识集合
*
* @param loginId 账号id
* @param loginKey 账号体系标识
* @return 该账号id具有的角色标识集合
*/
public List<String> getRoleList(Object loginId, String loginKey);
}
......@@ -4,7 +4,10 @@ import java.util.ArrayList;
import java.util.List;
/**
* 对StpInterface接口默认的实现类
* 对StpInterface接口默认的实现类
* <p>
* 如果开发者没有实现StpInterface接口,则使用此默认实现
*
* @author kong
*/
public class StpInterfaceDefaultImpl implements StpInterface {
......
......@@ -38,15 +38,15 @@ public class StpLogic {
public String loginKey = "";
/**
* 初始化StpLogic, 并制定loginKey
* @param loginKey 账号标识
* 初始化StpLogic, 并指定LoginKey
* @param loginKey 账号体系标识
*/
public StpLogic(String loginKey) {
this.loginKey = loginKey;
}
/**
* 获取当前StpLogin的loginKey
* 获取当前StpLogin的LoginKey
* @return 当前StpLogin的loginKey
*/
public String getLoginKey(){
......@@ -54,7 +54,7 @@ public class StpLogic {
}
/**
* 写入当前StpLogin的loginKey
* 写入当前StpLogin的LoginKey
* @param loginKey loginKey
* @return 对象自身
*/
......@@ -75,17 +75,16 @@ public class StpLogic {
}
/**
* 随机生成一个tokenValue
* 创建一个tokenValue
* @param loginId loginId
* @return 生成的tokenValue
*/
public String createTokenValue(Object loginId) {
// 去除掉所有逗号
return SaTokenManager.getSaTokenAction().createToken(loginId, loginKey).replaceAll(",", "");
return SaTokenManager.getSaTokenAction().createToken(loginId, loginKey);
}
/**
* 获取当前tokenValue
* 获取当前tokenValue
* @return 当前tokenValue
*/
public String getTokenValue(){
......@@ -100,15 +99,15 @@ public class StpLogic {
tokenValue = String.valueOf(request.getAttribute(getKeyJustCreatedSave()));
}
// 2. 尝试从请求体里面读取
if(tokenValue == null && config.getIsReadBody() == true){
if(tokenValue == null && config.getIsReadBody()){
tokenValue = request.getParameter(keyTokenName);
}
// 3. 尝试从header里读取
if(tokenValue == null && config.getIsReadHead() == true){
if(tokenValue == null && config.getIsReadHead()){
tokenValue = request.getHeader(keyTokenName);
}
// 4. 尝试从cookie里读取
if(tokenValue == null && config.getIsReadCookie() == true){
if(tokenValue == null && config.getIsReadCookie()){
Cookie cookie = SaTokenManager.getSaTokenCookie().getCookie(request, keyTokenName);
if(cookie != null){
tokenValue = cookie.getValue();
......@@ -156,7 +155,6 @@ public class StpLogic {
*/
public void setLoginId(Object loginId, String device) {
// ------ 1、获取相应对象
HttpServletRequest request = SaTokenManager.getSaTokenServlet().getRequest();
SaTokenConfig config = getConfig();
......@@ -166,7 +164,7 @@ public class StpLogic {
String tokenValue = null;
// --- 如果允许并发登录
if(config.getAllowConcurrentLogin() == true) {
// 如果配置为共享token, 则尝试从session签名记录里取出token
// 如果配置为共享token, 则尝试从Session签名记录里取出token
if(config.getIsShare() == true) {
tokenValue = getTokenValueByLoginId(loginId, device);
}
......@@ -178,19 +176,22 @@ public class StpLogic {
List<TokenSign> tokenSignList = session.getTokenSignList();
for (TokenSign tokenSign : tokenSignList) {
if(tokenSign.getDevice().equals(device)) {
dao.updateValue(getKeyTokenValue(tokenSign.getValue()), NotLoginException.BE_REPLACED); // 1. 将此token 标记为已顶替
clearLastActivity(tokenSign.getValue()); // 2. 清理掉[token-最后操作时间]
session.removeTokenSign(tokenSign.getValue()); // 3. 清理账号session上的token签名记录
// 1. 将此token 标记为已顶替
dao.updateValue(getKeyTokenValue(tokenSign.getValue()), NotLoginException.BE_REPLACED);
// 2. 清理掉[token-最后操作时间]
clearLastActivity(tokenSign.getValue());
// 3. 清理账号session上的token签名记录
session.removeTokenSign(tokenSign.getValue());
}
}
}
}
// 如果至此,仍未成功创建tokenValue
// 如果至此,仍未成功创建tokenValue, 则开始生成一个
if(tokenValue == null) {
tokenValue = createTokenValue(loginId);
}
// ------ 3. 获取[id-session] (如果还没有创建session, 则新建, 如果已经创建,则续期)
// ------ 3. 获取[User-Session] (如果还没有创建session, 则新建, 如果已经创建,则续期)
SaSession session = getSessionByLoginId(loginId, false);
if(session == null) {
session = getSessionByLoginId(loginId);
......@@ -201,10 +202,14 @@ public class StpLogic {
session.addTokenSign(new TokenSign(tokenValue, device));
// ------ 4. 持久化其它数据
dao.setValue(getKeyTokenValue(tokenValue), String.valueOf(loginId), config.getTimeout()); // token -> uid
request.setAttribute(getKeyJustCreatedSave(), tokenValue); // 将token保存到本次request里
setLastActivityToNow(tokenValue); // 写入 [最后操作时间]
if(config.getIsReadCookie() == true){ // cookie注入
// token -> uid
dao.setValue(getKeyTokenValue(tokenValue), String.valueOf(loginId), config.getTimeout());
// 将token保存到本次request里
request.setAttribute(getKeyJustCreatedSave(), tokenValue);
// 写入 [最后操作时间]
setLastActivityToNow(tokenValue);
// cookie注入
if(config.getIsReadCookie() == true){
SaTokenManager.getSaTokenCookie().addCookie(SaTokenManager.getSaTokenServlet().getResponse(), getTokenName(), tokenValue, "/", (int)config.getTimeout());
}
}
......@@ -240,14 +245,14 @@ public class StpLogic {
}
SaTokenManager.getSaTokenDao().deleteKey(getKeyTokenValue(tokenValue));
// 2. 尝试清理账号session上的token签名 (如果为null或已被标记为异常, 那么无需继续执行 )
// 3. 尝试清理账号session上的token签名 (如果为null或已被标记为异常, 那么无需继续执行 )
SaSession session = getSessionByLoginId(loginId, false);
if(session == null) {
return;
}
session.removeTokenSign(tokenValue);
// 3. 尝试注销session
// 4. 尝试注销session
session.logoutByTokenSignCountToZero();
}
......@@ -267,13 +272,13 @@ public class StpLogic {
* @param device 设备标识 (填null代表所有注销设备)
*/
public void logoutByLoginId(Object loginId, String device) {
// 先获取这个账号的[id-session], 如果为null,则不执行任何操作
// 1. 先获取这个账号的[id-session], 如果为null,则不执行任何操作
SaSession session = getSessionByLoginId(loginId);
if(session == null) {
return;
}
// 循环token签名列表,开始删除相关信息
// 2. 循环token签名列表,开始删除相关信息
List<TokenSign> tokenSignList = session.getTokenSignList();
for (TokenSign tokenSign : tokenSignList) {
if(device == null || tokenSign.getDevice().equals(device)) {
......@@ -282,12 +287,12 @@ public class StpLogic {
// 2. 清理掉[token-最后操作时间]
clearLastActivity(tokenValue);
// 3. 标记:已被踢下线
SaTokenManager.getSaTokenDao().updateValue(getKeyTokenValue(tokenValue), NotLoginException.KICK_OUT); // 标记:已被踢下线
SaTokenManager.getSaTokenDao().updateValue(getKeyTokenValue(tokenValue), NotLoginException.KICK_OUT);
// 4. 清理账号session上的token签名
session.removeTokenSign(tokenValue);
}
}
// 尝试注销session
// 3. 尝试注销session
session.logoutByTokenSignCountToZero();
}
......@@ -314,16 +319,16 @@ public class StpLogic {
* @return 账号id
*/
public Object getLoginId() {
// 如果正在[临时身份切换]
// 如果正在[临时身份切换], 则返回临时身份
if(isSwitch()) {
return getSwitchLoginId();
}
// 如果获取不到token,则抛出无token
// 如果获取不到token,则抛出: 无token
String tokenValue = getTokenValue();
if(tokenValue == null) {
throw NotLoginException.newInstance(loginKey, NotLoginException.NOT_TOKEN);
}
// 查找此token对应loginId, 则抛出:无效token
// 查找此token对应loginId, 如果找不到则抛出:无效token
String loginId = getLoginIdNotHandle(tokenValue);
if(loginId == null) {
throw NotLoginException.newInstance(loginKey, NotLoginException.INVALID_TOKEN);
......@@ -336,14 +341,14 @@ public class StpLogic {
if(loginId.equals(NotLoginException.BE_REPLACED)) {
throw NotLoginException.newInstance(loginKey, NotLoginException.BE_REPLACED);
}
// 如果是已经被踢下线了, 则抛出:已被踢下线
// 如果是已经被踢下线了, 则抛出:已被踢下线
if(loginId.equals(NotLoginException.KICK_OUT)) {
throw NotLoginException.newInstance(loginKey, NotLoginException.KICK_OUT);
}
// 检查是否已经 [临时过期],同时更新[最后操作时间]
checkActivityTimeout(tokenValue);
updateLastActivityToNow(tokenValue);
// 至此,返回loginId
// 至此,返回loginId
return loginId;
}
......@@ -387,7 +392,7 @@ public class StpLogic {
if(tokenValue == null) {
return null;
}
// loginId为null或者在异常项里面,均视为未登录
// loginId为null或者在异常项里面,均视为未登录, 返回null
Object loginId = getLoginIdNotHandle(tokenValue);
if(loginId == null || NotLoginException.ABNORMAL_LIST.contains(loginId)) {
return null;
......@@ -413,10 +418,6 @@ public class StpLogic {
* @return 账号id
*/
public int getLoginIdAsInt() {
// Object loginId = getLoginId();
// if(loginId instanceof Integer) {
// return (Integer)loginId;
// }
return Integer.valueOf(String.valueOf(getLoginId()));
}
......@@ -425,10 +426,6 @@ public class StpLogic {
* @return 账号id
*/
public long getLoginIdAsLong() {
// Object loginId = getLoginId();
// if(loginId instanceof Long) {
// return (Long)loginId;
// }
return Long.valueOf(String.valueOf(getLoginId()));
}
......@@ -553,11 +550,14 @@ public class StpLogic {
// 如果配置忽略token登录校验,则必须保证token不为null (token为null的时候随机创建一个)
String tokenValue = getTokenValue();
if(tokenValue == null || Objects.equals(tokenValue, "")) {
// 随机一个token送给ta
// 随机一个token送给Ta
tokenValue = createTokenValue(null);
// Request做上标记
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());
}
}
......@@ -801,7 +801,7 @@ public class StpLogic {
List<String> roleList = SaTokenManager.getStpInterface().getRoleList(loginId, loginKey);
for (String role : roleArray) {
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);
for (String role : roleArray) {
if(roleList.contains(role) == true) {
return; // 有的话提前退出
// 有的话提前退出
return;
}
}
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);
for (String permission : permissionArray) {
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);
for (String permission : permissionArray) {
if(permissionList.contains(permission) == true) {
return; // 有的话提前退出
// 有的话提前退出
return;
}
}
if(permissionArray.length > 0) {
throw new NotPermissionException(permissionArray[0], this.loginKey); // 没有权限抛出异常
throw new NotPermissionException(permissionArray[0], this.loginKey);
}
}
......
......@@ -37,7 +37,7 @@ public class StpUtil {
}
/**
* 获取当前tokenValue
* 获取当前tokenValue
* @return 当前tokenValue
*/
public static String getTokenValue() {
......
......@@ -51,6 +51,9 @@ public class SaTaskUtil {
* @author kong
*/
public static interface FunctionRunClass{
/**
* 要执行的方法
*/
public void run();
}
......
package cn.dev33.satoken.util;
/**
* 定义sa-token的所有常量
* sa-token常量类
* @author kong
*
*/
public class SaTokenConsts {
// =================== sa-token版本信息 ===================
/**
* sa-token 版本号
*/
......@@ -16,29 +19,62 @@ public class SaTokenConsts {
* 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_";
/**
* 如果本次请求已经验证过[无操作过期], 则以此值存储在当前request中 TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY
* 常量key标记: 如果本次请求已经验证过[无操作过期], 则以此值存储在当前request中
*/
public static final String TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY = "TOKEN_ACTIVITY_TIMEOUT_CHECKED_KEY_";
/**
* 在登录时,默认使用的设备名称
* 常量key标记: 在登录时,默认使用的设备名称
*/
public static final String DEFAULT_LOGIN_DEVICE = "default-device";
/**
* 在进行临时身份切换时使用的key
* 常量key标记: 在进行临时身份切换时使用的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";
}
......@@ -7,31 +7,28 @@ import java.util.List;
import java.util.Random;
/**
* sa-token 内部代码工具类
* sa-token 内部代码工具类
*
* @author kong
*
*/
public class SaTokenInsideUtil {
/**
* 打印 sa-token 版本字符画
* 打印 sa-token 版本字符画
*/
public static void printSaToken() {
String str =
"____ ____ ___ ____ _ _ ____ _ _ \r\n" +
"[__ |__| __ | | | |_/ |___ |\\ | \r\n" +
"___] | | | |__| | \\_ |___ | \\| \r\n" +
"sa-token:" + SaTokenConsts.VERSION_NO + " \r\n" +
"GitHub:" + SaTokenConsts.GITHUB_URL; // + "\r\n";
String str = "____ ____ ___ ____ _ _ ____ _ _ \r\n" + "[__ |__| __ | | | |_/ |___ |\\ | \r\n"
+ "___] | | | |__| | \\_ |___ | \\| \r\n" + "sa-token:" + SaTokenConsts.VERSION_NO
+ " \r\n" + "GitHub:" + SaTokenConsts.GITHUB_URL; // + "\r\n";
System.out.println(str);
}
/**
* 生成指定长度的随机字符串
* @param length 字符串的长度
* @return 一个随机字符串
* 生成指定长度的随机字符串
*
* @param length 字符串的长度
* @return 一个随机字符串
*/
public static String getRandomString(int length) {
String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
......@@ -43,68 +40,69 @@ public class SaTokenInsideUtil {
}
return sb.toString();
}
/**
* 以当前时间戳和随机int数字拼接一个随机字符串
* @return 随机字符串
* 以当前时间戳和随机int数字拼接一个随机字符串
*
* @return 随机字符串
*/
public static String getMarking28() {
return System.currentTimeMillis() + "" + new Random().nextInt(Integer.MAX_VALUE);
}
/**
* 从集合里查询数据
* @param dataList 数据集合
* @param prefix 前缀
* @param keyword 关键字
* @param start 起始位置 (-1代表查询所有)
* @param size 获取条数
* @return 符合条件的新数据集合
*
* @param dataList 数据集合
* @param prefix 前缀
* @param keyword 关键字
* @param start 起始位置 (-1代表查询所有)
* @param size 获取条数
* @return 符合条件的新数据集合
*/
public static List<String> searchList(Collection<String> dataList, String prefix, String keyword, int start, int size) {
if(prefix == null) {
public static List<String> searchList(Collection<String> dataList, String prefix, String keyword, int start,
int size) {
if (prefix == null) {
prefix = "";
}
if(keyword == null) {
if (keyword == null) {
keyword = "";
}
// 挑选出所有符合条件的
// 挑选出所有符合条件的
List<String> list = new ArrayList<String>();
Iterator<String> keys = dataList.iterator();
while (keys.hasNext()) {
String key = keys.next();
if(key.startsWith(prefix) && key.indexOf(keyword) > -1) {
if (key.startsWith(prefix) && key.indexOf(keyword) > -1) {
list.add(key);
}
}
// 取指定段数据
return searchList(list, start, size);
}
/**
* 从集合里查询数据
* @param list 数据集合
*
* @param list 数据集合
* @param start 起始位置 (-1代表查询所有)
* @param size 获取条数
* @return 符合条件的新数据集合
* @param size 获取条数
* @return 符合条件的新数据集合
*/
public static List<String> searchList(List<String> list, int start, int size) {
// 取指定段数据
if(start < 0) {
if (start < 0) {
return list;
}
int end = start + size;
List<String> list2 = new ArrayList<String>();
for (int i = start; i < end; i++) {
if(i >= list.size()) {
if (i >= list.size()) {
return list2;
}
list2.add(list.get(i));
}
return list2;
}
}
......@@ -21,7 +21,10 @@ import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.util.SaTokenInsideUtil;
/**
* sa-token持久层的实现类, 基于redis (to jackson)
* sa-token持久层的实现类, 基于redis (使用 jackson 序列化方式)
*
* @author kong
*
*/
@Component
public class SaTokenDaoRedisJackson implements SaTokenDao {
......@@ -97,7 +100,8 @@ public class SaTokenDaoRedisJackson implements SaTokenDao {
@Override
public void updateValue(String key, String value) {
long expire = getTimeout(key);
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) { // -2 = 无此键
// -2 = 无此键
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) {
return;
}
this.setValue(key, value, expire);
......@@ -167,7 +171,8 @@ public class SaTokenDaoRedisJackson implements SaTokenDao {
@Override
public void updateSession(SaSession session) {
long expire = getSessionTimeout(session.getId());
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) { // -2 = 无此键
// -2 = 无此键
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) {
return;
}
this.saveSession(session, expire);
......
......@@ -18,12 +18,15 @@ import cn.dev33.satoken.util.SaTokenInsideUtil;
/**
* sa-token持久层的实现类, 基于redis
*
* @author kong
*
*/
@Component
public class SaTokenDaoRedis implements SaTokenDao {
/**
* string专用
* string专用
*/
@Autowired
public StringRedisTemplate stringRedisTemplate;
......@@ -52,7 +55,7 @@ public class SaTokenDaoRedis implements SaTokenDao {
/**
* 根据key获取value,如果没有,则返回空
* 根据key获取value,如果没有,则返回空
*/
@Override
public String getValue(String key) {
......@@ -78,7 +81,8 @@ public class SaTokenDaoRedis implements SaTokenDao {
@Override
public void updateValue(String key, String value) {
long expire = getTimeout(key);
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) { // -2 = 无此键
// -2 = 无此键
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) {
return;
}
this.setValue(key, value, expire);
......@@ -148,7 +152,8 @@ public class SaTokenDaoRedis implements SaTokenDao {
@Override
public void updateSession(SaSession session) {
long expire = getSessionTimeout(session.getId());
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) { // -2 = 无此键
// -2 = 无此键
if(expire == SaTokenDao.NOT_VALUE_EXPIRE) {
return;
}
this.saveSession(session, expire);
......
......@@ -11,7 +11,8 @@ import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil;
/**
* sa-token 基于 Spring Aop 的注解鉴权
* sa-token 基于 Spring Aop 的注解鉴权
*
* @author kong
*/
@Aspect
......@@ -19,46 +20,46 @@ import cn.dev33.satoken.stp.StpUtil;
public class SaCheckAspect {
/**
*
*
*/
public SaCheckAspect() {
}
/**
* 获取本切面使用的StpLogic
* 获取本切面使用的StpLogic
*/
public StpLogic getStpLogic() {
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) || "
+ "@within(cn.dev33.satoken.annotation.SaCheckRole) || @annotation(cn.dev33.satoken.annotation.SaCheckRole) || "
+ "@within(cn.dev33.satoken.annotation.SaCheckPermission) || @annotation(cn.dev33.satoken.annotation.SaCheckPermission)";
/**
* 声明AOP签名
* 声明AOP签名
*/
@Pointcut(POINTCUT_SIGN)
public void pointcut() {
}
/**
* 环绕切入
* 环绕切入
*
* @param joinPoint 切面对象
* @return 底层方法执行后的返回值
* @throws Throwable 底层方法抛出的异常
* @throws Throwable 底层方法抛出的异常
*/
@Around("pointcut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
// 注解鉴权
// 注解鉴权
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
getStpLogic().checkMethodAnnotation(signature.getMethod());
try {
// 执行原有逻辑
// 执行原有逻辑
Object obj = joinPoint.proceed();
return obj;
} catch (Throwable e) {
......
......@@ -16,102 +16,108 @@ import cn.dev33.satoken.spring.SaTokenServletSpringImpl;
import cn.dev33.satoken.stp.StpInterface;
/**
* 利用spring的自动装配来加载开发者重写的Bean
* 利用spring的自动装配来加载开发者重写的Bean
*
* @author kong
*
*/
@Component
public class SaTokenSpringAutowired {
/**
* 获取配置Bean
* @return 配置对象
* 获取配置Bean
*
* @return 配置对象
*/
@Bean
@ConfigurationProperties(prefix="spring.sa-token")
@ConfigurationProperties(prefix = "spring.sa-token")
public SaTokenConfig getSaTokenConfig() {
return new SaTokenConfig();
}
/**
* 注入配置Bean
* 注入配置Bean
*
* @param saTokenConfig 配置对象
*/
@Autowired
public void setConfig(SaTokenConfig saTokenConfig){
public void setConfig(SaTokenConfig saTokenConfig) {
SaTokenManager.setConfig(saTokenConfig);
}
/**
* 注入持久化Bean
* @param saTokenDao .
* 注入持久化Bean
*
* @param saTokenDao SaTokenDao对象
*/
@Autowired(required = false)
public void setSaTokenDao(SaTokenDao saTokenDao){
public void setSaTokenDao(SaTokenDao saTokenDao) {
SaTokenManager.setSaTokenDao(saTokenDao);
}
/**
* 注入权限认证Bean
* @param stpInterface .
* 注入权限认证Bean
*
* @param stpInterface StpInterface对象
*/
@Autowired(required = false)
public void setStpInterface(StpInterface stpInterface){
public void setStpInterface(StpInterface stpInterface) {
SaTokenManager.setStpInterface(stpInterface);
}
/**
* 注入Cookie操作Bean
* @param saTokenCookie .
* 注入Cookie操作Bean
*
* @param saTokenCookie SaTokenCookie对象
*/
@Autowired(required = false)
public void setSaTokenCookie(SaTokenCookie saTokenCookie){
public void setSaTokenCookie(SaTokenCookie saTokenCookie) {
SaTokenManager.setSaTokenCookie(saTokenCookie);
}
/**
* 注入框架行为Bean
* @param saTokenAction .
* 注入框架行为Bean
*
* @param saTokenAction SaTokenAction对象
*/
@Autowired(required = false)
public void setSaTokenAction(SaTokenAction saTokenAction){
public void setSaTokenAction(SaTokenAction saTokenAction) {
SaTokenManager.setSaTokenAction(saTokenAction);
}
/**
* 获取Servlet操作Bean (Spring版)
* @return Servlet操作Bean (Spring版)
* 获取Servlet操作Bean (Spring版)
*
* @return Servlet操作Bean (Spring版)
*/
@Bean
public SaTokenServlet getSaTokenServlet() {
return new SaTokenServletSpringImpl();
}
/**
* 注入Servlet操作Bean
* @param saTokenServlet .
* 注入Servlet操作Bean
*
* @param saTokenServlet SaTokenServlet对象
*/
@Autowired
public void setSaTokenServlet(SaTokenServlet saTokenServlet){
public void setSaTokenServlet(SaTokenServlet saTokenServlet) {
SaTokenManager.setSaTokenServlet(saTokenServlet);
}
/**
* 路由匹配器
* 路由匹配器
*/
public static PathMatcher pathMatcher;
/**
* 利用自动匹配特性,获取SpringMVC框架内部使用的路由匹配器
* 利用自动匹配特性,获取SpringMVC框架内部使用的路由匹配器
*
* @param pathMatcher 要设置的 pathMatcher
*/
@Autowired(required = false)
public static void setPathMatcher(PathMatcher pathMatcher) {
SaTokenSpringAutowired.pathMatcher = pathMatcher;
}
}
......@@ -12,29 +12,29 @@ import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil;
/**
* 注解式鉴权 - 拦截器
* 注解式鉴权 - 拦截器
*
* @author kong
*/
public class SaAnnotationInterceptor implements HandlerInterceptor {
/**
* 底层的 StpLogic 对象
* 在进行注解鉴权时使用的 StpLogic 对象
*/
public StpLogic stpLogic = null;
/**
* @return 底层的 StpLogic 对象
* @return 在进行注解鉴权时使用的 StpLogic 对象
*/
public StpLogic getStpLogic() {
if(stpLogic == null) {
if (stpLogic == null) {
stpLogic = StpUtil.stpLogic;
}
return stpLogic;
}
/**
* @param stpLogic 底层的 StpLogic 对象
* @param stpLogic 在进行注解鉴权时使用的 StpLogic 对象
* @return 拦截器自身
*/
public SaAnnotationInterceptor setStpLogic(StpLogic stpLogic) {
......@@ -42,33 +42,30 @@ public class SaAnnotationInterceptor implements HandlerInterceptor {
return this;
}
/**
* 创建,并指定一个默认的 StpLogic
* 构建: 注解式鉴权 - 拦截器
*/
public SaAnnotationInterceptor() {
}
/**
* 每次请求之前触发的方法
* 每次请求之前触发的方法
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 获取处理method
if (handler instanceof HandlerMethod == false) {
return true;
}
Method method = ((HandlerMethod) handler).getMethod();
// 进行验证
// 进行验证
getStpLogic().checkMethodAnnotation(method);
// 通过验证
// 通过验证
return true;
}
}
......@@ -5,16 +5,18 @@ import javax.servlet.http.HttpServletResponse;
/**
* 执行验证方法的辅助类
*
* @author kong
*
*/
public interface SaRouteFunction {
/**
* 执行验证的方法
* @param request request对象
* @param response response对象
* @param handler 处理对象
* 执行验证的方法
*
* @param request request对象
* @param response response对象
* @param handler 处理对象
*/
public void run(HttpServletRequest request, HttpServletResponse response, Object handler);
......
......@@ -19,7 +19,7 @@ import cn.dev33.satoken.fun.SaFunction;
public class SaRouterUtil {
/**
* 在进行路由匹配时所使用的 PathMatcher 对象
* 在进行路由匹配时所使用的 PathMatcher 对象
*/
private static PathMatcher pathMatcher;
......
......@@ -6,14 +6,15 @@ import javax.servlet.http.HttpServletResponse;
import cn.dev33.satoken.servlet.SaTokenServlet;
/**
* sa-token 对cookie的相关操作 接口实现类
* sa-token 对cookie的相关操作 接口实现类
*
* @author kong
*
*/
public class SaTokenServletSpringImpl implements SaTokenServlet {
/**
* 获取当前请求的Request对象
* 获取当前请求的Request对象
*/
@Override
public HttpServletRequest getRequest() {
......@@ -21,11 +22,11 @@ public class SaTokenServletSpringImpl implements SaTokenServlet {
}
/**
* 获取当前请求的Response对象
* 获取当前请求的Response对象
*/
@Override
public HttpServletResponse getResponse() {
return SpringMVCUtil.getResponse();
}
}
......@@ -6,6 +6,8 @@ import javax.servlet.http.HttpServletResponse;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import cn.dev33.satoken.exception.SaTokenException;
/**
* SpringMVC相关操作
* @author kong
......@@ -18,9 +20,9 @@ public class SpringMVCUtil {
* @return request
*/
public static HttpServletRequest getRequest() {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();// 大善人SpringMVC提供的封装
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if(servletRequestAttributes == null) {
throw new RuntimeException("当前环境非JavaWeb");
throw new SaTokenException("非Web上下文无法获取Request");
}
return servletRequestAttributes.getRequest();
}
......@@ -30,9 +32,9 @@ public class SpringMVCUtil {
* @return response
*/
public static HttpServletResponse getResponse() {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();// 大善人SpringMVC提供的封装
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if(servletRequestAttributes == null) {
throw new RuntimeException("当前环境非JavaWeb");
throw new SaTokenException("非Web上下文无法获取Request");
}
return servletRequestAttributes.getResponse();
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册