第一版

This commit is contained in:
2020-02-05 00:31:51 +08:00
parent 9a372b742d
commit 3329910bdd
38 changed files with 2079 additions and 0 deletions

View File

@@ -0,0 +1,78 @@
package cn.dev33.satoken;
import cn.dev33.satoken.config.SaTokenConfig;
import cn.dev33.satoken.config.SaTokenConfigFactory;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.dao.SaTokenDaoDefault;
import cn.dev33.satoken.stp.StpInterface;
import cn.dev33.satoken.stp.StpInterfaceDefaultImpl;
/**
* 管理sa-token所有对象
* @author kong
*
*/
public class SaTokenManager {
// 配置文件 Bean
private static SaTokenConfig config;
public static SaTokenConfig getConfig() {
if (config == null) {
initConfig();
}
return config;
}
public static void setConfig(SaTokenConfig config) {
SaTokenManager.config = config;
if(config.getIsV()) {
SaTokenUtil.printSaToken();
}
}
public synchronized static void initConfig() {
if (config == null) {
setConfig(SaTokenConfigFactory.createConfig());
}
}
// 持久化 Bean
public static SaTokenDao dao;
public static SaTokenDao getDao() {
if (dao == null) {
initDao();
}
return dao;
}
public static void setDao(SaTokenDao dao) {
SaTokenManager.dao = dao;
}
public synchronized static void initDao() {
if (dao == null) {
setDao(new SaTokenDaoDefault());
}
}
// 权限认证 Bean
public static StpInterface stp;
public static StpInterface getStp() {
if (stp == null) {
initStp();
}
return stp;
}
public static void setStp(StpInterface stp) {
SaTokenManager.stp = stp;
}
public synchronized static void initStp() {
if (stp == null) {
setStp(new StpInterfaceDefaultImpl());
}
}
}

View File

@@ -0,0 +1,30 @@
package cn.dev33.satoken;
/**
* sa-token 工具类
*/
public class SaTokenUtil {
// sa-token 版本号
public static final String version = "v1.0.0";
// sa-token 开源地址
public static final String github_url = "https://github.com/click33/sa-token";
// 打印 sa-token
public static void printSaToken() {
String str =
"____ ____ ___ ____ _ _ ____ _ _ \r\n" +
"[__ |__| __ | | | |_/ |___ |\\ | \r\n" +
"___] | | | |__| | \\_ |___ | \\| \r\n" +
"sa-token" + version + " \r\n" +
"GitHub" + github_url + "\r\n";
System.out.println(str);
}
// 如果token为本次请求新创建的则以此字符串为key存储在当前request中
public static final String just_created_save_key= "just_created_save_key_";
}

View File

@@ -0,0 +1,65 @@
package cn.dev33.satoken.config;
/**
* sa-token 总配置类
*/
public class SaTokenConfig {
private String tokenName = "satoken"; // token名称同时也是cookie名称
private long timeout = 30 * 24 * 60 * 60; // token有效期单位s 默认30天-1为永不过期
private Boolean isShare = true; // 在多人登录同一账号时是否共享会话为true时共用一个为false时新登录挤掉旧登录
private Boolean isReadHead = false; // 是否在cookie读取不到token时继续从请求header里继续尝试读取
private Boolean isReadBody = false; // 是否在header读取不到token时继续从请求题参数里继续尝试读取
private Boolean isV = true; // 是否在初始化配置时打印版本字符画
public String getTokenName() {
return tokenName;
}
public void setTokenName(String tokenName) {
this.tokenName = tokenName;
}
public long getTimeout() {
return timeout;
}
public void setTimeout(long timeout) {
this.timeout = timeout;
}
public Boolean getIsShare() {
return isShare;
}
public void setIsShare(Boolean isShare) {
this.isShare = isShare;
}
public Boolean getIsReadHead() {
return isReadHead;
}
public void setIsReadHead(Boolean isReadHead) {
this.isReadHead = isReadHead;
}
public Boolean getIsReadBody() {
return isReadBody;
}
public void setIsReadBody(Boolean isReadBody) {
this.isReadBody = isReadBody;
}
public Boolean getIsV() {
return isV;
}
public void setIsV(Boolean isV) {
this.isV = isV;
}
@Override
public String toString() {
return "SaTokenConfig [tokenName=" + tokenName + ", timeout=" + timeout + ", isShare=" + isShare
+ ", isReadHead=" + isReadHead + ", isReadBody=" + isReadBody + ", isV=" + isV + "]";
}
}

View File

@@ -0,0 +1,128 @@
package cn.dev33.satoken.config;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
创建一个配置文件
*/
public class SaTokenConfigFactory {
public static String configPath = "sa-token.properties"; // 默认配置文件地址
/**
* 根据指定路径获取配置信息
* @return 一个SaTokenConfig对象
*/
public static SaTokenConfig createConfig() {
Map<String, String> map = readPropToMap(configPath);
if(map == null){
// throw new RuntimeException("找不到配置文件:" + configPath, null);
}
return (SaTokenConfig)initPropByMap(map, new SaTokenConfig());
}
/**
* 将指定路径的properties配置文件读取到Map中
* @param propertiesPath 配置文件地址
* @return 一个Map
*/
private static Map<String, String> readPropToMap(String propertiesPath){
Map<String, String> map = new HashMap<String, String>();
try {
InputStream is = SaTokenConfigFactory.class.getClassLoader().getResourceAsStream(propertiesPath);
if(is == null){
return null;
}
Properties prop = new Properties();
prop.load(is);
for (String key : prop.stringPropertyNames()) {
map.put(key, prop.getProperty(key));
}
} catch (IOException e) {
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<>();
}
// 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; // 如果为空代表没有配置此项
}
try {
Object valueConvert = getObjectByClass(value, field.getType()); // 转换值类型
field.setAccessible(true);
field.set(obj, valueConvert);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new RuntimeException("属性赋值出错:" + field.getName(), e);
}
}
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;
}
}

View File

@@ -0,0 +1,61 @@
package cn.dev33.satoken.dao;
import cn.dev33.satoken.session.SaSession;
/**
* sa-token持久层的接口
*/
public interface SaTokenDao {
/**
* 根据key获取value ,如果没有,则返回空
* @param key 键名称
* @return
*/
public String getValue(String key);
/**
* 写入指定key-value键值对并设定过期时间 (单位:秒)
* @param key 键名称
* @param value 值
* @param timeout 过期时间单位s
*/
public void setValue(String key, String value, long timeout);
/**
* 删除一个指定的key
* @param key
*/
public void delKey(String key);
/**
* 根据指定key的session如果没有则返回空
* @param key 键名称
* @return
*/
public SaSession getSaSession(String sessionId);
/**
* 将指定session持久化
* @param key 键名称
* @param value 值
* @param timeout 过期时间,单位: s
*/
public void saveSaSession(SaSession session, long timeout);
/**
* 更新指定session
*/
public void updateSaSession(SaSession session);
/**
* 删除一个指定的session
* @param key 键名称
*/
public void delSaSession(String sessionId);
}

View File

@@ -0,0 +1,62 @@
package cn.dev33.satoken.dao;
import java.util.HashMap;
import java.util.Map;
import cn.dev33.satoken.session.SaSession;
/**
* sa-token持久层默认的实现类 , 基于内存Map
*/
public class SaTokenDaoDefault implements SaTokenDao {
/**
* 所有数据集合
*/
Map<String, Object> dataMap = new HashMap<String, Object>();
@Override
public String getValue(String key) {
return (String)dataMap.get(key);
}
@Override
public void setValue(String key, String value, long timeout) {
dataMap.put(key, value);
}
@Override
public void delKey(String key) {
dataMap.remove(key);
}
@Override
public SaSession getSaSession(String sessionId) {
return (SaSession)dataMap.get(sessionId);
}
@Override
public void saveSaSession(SaSession session, long timeout) {
dataMap.put(session.getId(), session);
}
@Override
public void updateSaSession(SaSession session) {
// 无动作
}
@Override
public void delSaSession(String sessionId) {
dataMap.remove(sessionId);
}
}

View File

@@ -0,0 +1,21 @@
package cn.dev33.satoken.exception;
/**
* 没有登陆抛出的异常
*/
public class NotLoginException extends RuntimeException {
/**
*
*/
private static final long serialVersionUID = 6806129545290130142L;
/**
* 创建一个
*/
public NotLoginException() {
super("当前账号未登录");
}
}

View File

@@ -0,0 +1,33 @@
package cn.dev33.satoken.exception;
/**
* 没有指定权限码,抛出的异常
*/
public class NotPermissionException extends RuntimeException {
/**
*
*/
private static final long serialVersionUID = 6806129545290130142L;
private Object code;
/**
* @return 获得权限码
*/
public Object getCode() {
return code;
}
public NotPermissionException(Object code) {
super("无此权限:" + code);
this.code = code;
}
// public NotPermissionException(Object code, String s) {
// super(s);
// this.code = code;
// }
}

View File

@@ -0,0 +1,129 @@
package cn.dev33.satoken.session;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import cn.dev33.satoken.SaTokenManager;
/**
* session会话
* @author kong
*
*/
public class SaSession implements Serializable {
private static final long serialVersionUID = 1L;
private String id; // 会话id
private long createTime; // 当前会话创建时间
private Map<String, Object> dataMap; // 当前会话键值对
/**
* 构建一个 session对象
* @param id
*/
public SaSession(String id) {
this.id = id;
this.createTime = System.currentTimeMillis();
this.dataMap = new HashMap<String, Object>();
}
/**
* 获取会话id
* @return
*/
public String getId() {
return id;
}
/**
* 当前会话创建时间
*/
public long getCreateTime() {
return createTime;
}
/**
* 写入值
*/
public void setAttribute(String key, Object value) {
dataMap.put(key, value);
update();
}
/**
* 取值
*/
public Object getAttribute(String key) {
return dataMap.get(key);
}
/**
* 取值,并指定取不到值时的默认值
*/
public Object getAttribute(String key, Object default_value) {
Object value = getAttribute(key);
if(value != null) {
return value;
}
return default_value;
}
/**
* 移除一个key
*/
public void removeAttribute(String key) {
dataMap.remove(key);
update();
}
/**
* 清空所有key
*/
public void clearAttribute() {
dataMap.clear();
update();
}
/**
* 是否含有指定key
*/
public boolean containsAttribute(String key) {
return dataMap.keySet().contains(key);
}
/**
* 当前session会话所有key
*/
public Set<String> getAttributeKeys() {
return dataMap.keySet();
}
/**
* 获取数据集合如果更新map里的值请调用session.update()方法避免数据过时
*/
public Map<String, Object> getDataMap() {
return dataMap;
}
/**
* 将这个session从持久库更新一下
*/
public void update() {
SaTokenManager.getDao().updateSaSession(this);
}
// /** 注销会话(注销后此session会话将不再存储服务器上) */
// public void logout() {
// SaTokenManager.getDao().delSaSession(this.id);
// }
}

View File

@@ -0,0 +1,44 @@
package cn.dev33.satoken.session;
import cn.dev33.satoken.SaTokenManager;
/**
* sa-session工具类
* @author kong
*
*/
public class SaSessionUtil {
// 添加上指定前缀防止恶意伪造session
public static String session_key = "custom";
public static String getSessionKey(String sessionId) {
return SaTokenManager.getConfig().getTokenName() + ":" + session_key + ":session:" + sessionId;
}
/** 指定key的session是否存在 */
public boolean isExists(String sessionId) {
return SaTokenManager.getDao().getSaSession(getSessionKey(sessionId)) != null;
}
/** 获取指定key的session, 如果没有is_create=是否新建并返回 */
public static SaSession getSessionById(String sessionId, boolean is_create) {
SaSession session = SaTokenManager.getDao().getSaSession(getSessionKey(sessionId));
if(session == null && is_create) {
session = new SaSession(getSessionKey(sessionId));
SaTokenManager.getDao().saveSaSession(session, SaTokenManager.getConfig().getTimeout());
}
return session;
}
/** 获取指定key的session, 如果没有则新建并返回 */
public static SaSession getSessionById(String sessionId) {
return getSessionById(sessionId, true);
}
/** 删除指定key的session */
public static void delSessionById(String sessionId) {
SaTokenManager.getDao().delSaSession(getSessionKey(sessionId));
}
}

View File

@@ -0,0 +1,21 @@
package cn.dev33.satoken.spring;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* 将此注解加到springboot启动类上即可完成sa-token与springboot的集成
*/
@Documented
@Target({java.lang.annotation.ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Configuration
@Import({SpringSaToken.class})
public @interface SaTokenSetup {
}

View File

@@ -0,0 +1,48 @@
package cn.dev33.satoken.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import cn.dev33.satoken.SaTokenManager;
import cn.dev33.satoken.config.SaTokenConfig;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.stp.StpInterface;
/**
* 与SpringBoot集成, 保证此类被扫描即可完成sa-token与SpringBoot的集成
* @author kongyongshun
*
*/
@Component
public class SpringSaToken {
// 获取配置Bean
@Bean
@ConfigurationProperties(prefix="spring.sa-token")
public SaTokenConfig getSaTokenConfig() {
return new SaTokenConfig();
}
// 注入配置Bean
@Autowired
public void setConfig(SaTokenConfig saTokenConfig){
SaTokenManager.setConfig(saTokenConfig);
}
// 注入持久化Bean
@Autowired(required = false)
public void setDao(SaTokenDao dao){
SaTokenManager.setDao(dao);
}
// 注入权限认证Bean
@Autowired(required = false)
public void setStp(StpInterface stp){
SaTokenManager.setStp(stp);
}
}

View File

@@ -0,0 +1,14 @@
package cn.dev33.satoken.stp;
import java.util.List;
/**
* 开放权限验证接口,方便重写
*/
public interface StpInterface {
/** 返回指定login_id所拥有的权限码集合 */
public List<Object> getPermissionCodeList(Object login_id, String login_key);
}

View File

@@ -0,0 +1,16 @@
package cn.dev33.satoken.stp;
import java.util.ArrayList;
import java.util.List;
/**
* 权限验证接口 ,默认实现
*/
public class StpInterfaceDefaultImpl implements StpInterface {
@Override
public List<Object> getPermissionCodeList(Object login_id, String login_key) {
return new ArrayList<Object>();
}
}

View File

@@ -0,0 +1,306 @@
package cn.dev33.satoken.stp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import cn.dev33.satoken.SaTokenManager;
import cn.dev33.satoken.SaTokenUtil;
import cn.dev33.satoken.config.SaTokenConfig;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.util.SaCookieUtil;
import cn.dev33.satoken.util.SpringMVCUtil;
/**
* sa-token 权限验证,逻辑 实现类
* <p>
* (stp = sa-token-permission 的缩写 )
*
*/
public class StpLogic {
private String login_key = ""; // 持久化的key前缀多账号体系时以此值区分比如login、user、admin
public StpLogic(String login_key) {
this.login_key = login_key;
}
// =================== 获取token 相关 ===================
/** 随机生成一个tokenValue */
public String randomTokenValue() {
return UUID.randomUUID().toString();
}
/** 获取当前tokenValue */
public String getTokenValue(){
// 0、获取相应对象
HttpServletRequest request = SpringMVCUtil.getRequest();
SaTokenConfig config = SaTokenManager.getConfig();
String key_tokenName = getKey_tokenName();
// 1、尝试从request里读取
if(request.getAttribute(SaTokenUtil.just_created_save_key) != null) {
return String.valueOf(request.getAttribute(SaTokenUtil.just_created_save_key));
}
// 2、尝试从cookie里读取
Cookie cookie = SaCookieUtil.getCookie(request, key_tokenName);
if(cookie != null){
String tokenValue = cookie.getValue();
if(tokenValue != null) {
return tokenValue;
}
}
// 3、尝试从header力读取
if(config.getIsReadHead() == true){
String tokenValue = request.getHeader(key_tokenName);
if(tokenValue != null) {
return tokenValue;
}
}
// 4、尝试从请求体里面读取
if(config.getIsReadBody() == true){
String tokenValue = request.getParameter(key_tokenName);
if(tokenValue != null) {
return tokenValue;
}
}
// 5、都读取不到那算了吧还是
return null;
}
/** 获取指定id的tokenValue */
public String getTokenValueByLoginId(Object login_id) {
return SaTokenManager.getDao().getValue(getKey_LoginId(login_id));
}
/** 获取当前会话的token信息tokenName与tokenValue */
public Map<String, String> getTokenInfo() {
Map<String, String> map = new HashMap<String, String>();
map.put("tokenName", getKey_tokenName());
map.put("tokenValue", getTokenValue());
return map;
}
// =================== 登录相关操作 ===================
/** 在当前会话上登录id 建议的类型long | int | String */
public void setLoginId(Object login_id) {
// 1、获取相应对象
HttpServletRequest request = SpringMVCUtil.getRequest();
SaTokenConfig config = SaTokenManager.getConfig();
SaTokenDao dao = SaTokenManager.getDao();
// 2、获取tokenValue
String tokenValue = getTokenValueByLoginId(login_id); // 获取旧tokenValue
if(tokenValue == null){ // 为null则创建一个新的
tokenValue = randomTokenValue();
} else {
// 不为null, 并且配置不共享,则删掉原来,并且创建新的
if(config.getIsShare() == false){
dao.delKey(getKey_TokenValue(tokenValue));
tokenValue = randomTokenValue();
}
}
// 3、持久化
dao.setValue(getKey_TokenValue(tokenValue), String.valueOf(login_id), config.getTimeout()); // token -> uid
dao.setValue(getKey_LoginId(login_id), tokenValue, config.getTimeout()); // uid -> token
request.setAttribute(SaTokenUtil.just_created_save_key, tokenValue); // 保存到本次request里
SaCookieUtil.addCookie(SpringMVCUtil.getResponse(), getKey_tokenName(), tokenValue, "/", (int)config.getTimeout()); // cookie注入
}
/** 当前会话注销登录 */
public void logout() {
Object login_id = getLoginId_defaultNull();
if(login_id != null) {
logoutByLoginId(login_id);
SaCookieUtil.delCookie(SpringMVCUtil.getRequest(), SpringMVCUtil.getResponse(), getKey_tokenName()); // 清除cookie
}
}
/** 指定login_id的会话注销登录踢人下线 */
public void logoutByLoginId(Object login_id) {
// 获取相应tokenValue
String tokenValue = getTokenValueByLoginId(login_id);
if(tokenValue == null) {
return;
}
// 清除相关数据
SaTokenManager.getDao().delKey(getKey_TokenValue(tokenValue)); // 清除token-id键值对
SaTokenManager.getDao().delKey(getKey_LoginId(login_id)); // 清除id-token键值对
SaTokenManager.getDao().delKey(getKey_session(login_id)); // 清除其session
// SaCookieUtil.delCookie(SpringMVCUtil.getRequest(), SpringMVCUtil.getResponse(), getKey_tokenName()); // 清除cookie
}
// 查询相关
/** 获取当前会话是否已经登录 */
public boolean isLogin() {
return getLoginId_defaultNull() != null;
}
/** 获取当前会话登录id, 如果未登录,则抛出异常 */
public Object getLoginId() {
Object login_id = getLoginId_defaultNull();
if(login_id == null) {
throw new NotLoginException();
}
return login_id;
}
/** 获取当前会话登录id, 如果未登录,则返回默认值 */
@SuppressWarnings("unchecked")
public <T>T getLoginId(T default_value) {
Object login_id = getLoginId_defaultNull();
if(login_id == null) {
return default_value;
}
return (T)login_id;
}
/** 获取当前会话登录id, 如果未登录则返回null */
public Object getLoginId_defaultNull() {
String tokenValue = getTokenValue();
if(tokenValue != null) {
Object login_id = SaTokenManager.getDao().getValue(getKey_TokenValue(tokenValue));
if(login_id != null) {
return login_id;
}
}
return null;
}
/** 获取当前会话登录id, 并转换为String */
public String getLoginId_asString() {
return String.valueOf(getLoginId());
}
/** 获取当前会话登录id, 并转换为int */
public int getLoginId_asInt() {
// Object login_id = getLoginId();
// if(login_id instanceof Integer) {
// return (Integer)login_id;
// }
return Integer.valueOf(String.valueOf(getLoginId()));
}
/** 获取当前会话登录id, 并转换为long */
public long getLoginId_asLong() {
// Object login_id = getLoginId();
// if(login_id instanceof Long) {
// return (Long)login_id;
// }
return Long.valueOf(String.valueOf(getLoginId()));
}
// =================== session相关 ===================
/** 获取指定key的session, 如果没有is_create=是否新建并返回 */
protected SaSession getSessionBySessionId(String sessionId, boolean is_create) {
SaSession session = SaTokenManager.getDao().getSaSession(sessionId);
if(session == null && is_create) {
session = new SaSession(sessionId);
SaTokenManager.getDao().saveSaSession(session, SaTokenManager.getConfig().getTimeout());
}
return session;
}
/** 获取指定login_id的session */
public SaSession getSessionByLoginId(Object login_id) {
return getSessionBySessionId(getKey_session(login_id), false);
}
/** 获取当前会话的session */
public SaSession getSession() {
return getSessionBySessionId(getKey_session(getLoginId()), true);
}
// =================== 权限验证操作 ===================
/** 指定login_id是否含有指定权限 */
public boolean hasPermission(Object login_id, Object pcode) {
List<Object> pcodeList = SaTokenManager.getStp().getPermissionCodeList(login_id, login_key);
return !(pcodeList == null || pcodeList.contains(pcode) == false);
}
/** 当前会话是否含有指定权限 */
public boolean hasPermission(Object pcode) {
return hasPermission(getLoginId(), pcode);
}
/** 当前账号是否含有指定权限 没有就抛出异常 */
public void checkPermission(Object pcode) {
if(hasPermission(pcode) == false) {
throw new NotPermissionException(pcode);
}
}
/** 当前账号是否含有指定权限 【指定多个,必须全都有】 */
public void checkPermissionAnd(Object... pcodeArray){
Object login_id = getLoginId();
List<Object> pcodeList = SaTokenManager.getStp().getPermissionCodeList(login_id, login_key);
for (Object pcode : pcodeArray) {
if(pcodeList.contains(pcode) == false) {
throw new NotPermissionException(pcode); // 没有权限抛出异常
}
}
}
/** 当前账号是否含有指定权限 【指定多个,有一个就可以了】 */
public void checkPermissionOr(Object... pcodeArray){
Object login_id = getLoginId();
List<Object> pcodeList = SaTokenManager.getStp().getPermissionCodeList(login_id, login_key);
for (Object pcode : pcodeArray) {
if(pcodeList.contains(pcode) == true) {
return; // 有的话提前退出
}
}
if(pcodeArray.length > 0) {
throw new NotPermissionException(pcodeArray[0]); // 没有权限抛出异常
}
}
// =================== 返回相应key ===================
/** 获取key客户端 tokenName */
public String getKey_tokenName() {
return SaTokenManager.getConfig().getTokenName();
}
/** 获取key tokenValue 持久化 */
public String getKey_TokenValue(String tokenValue) {
return SaTokenManager.getConfig().getTokenName() + ":" + login_key + ":token:" + tokenValue;
}
/** 获取key id 持久化 */
public String getKey_LoginId(Object login_id) {
return SaTokenManager.getConfig().getTokenName() + ":" + login_key + ":id:" + login_id;
}
/** 获取key session 持久化 */
public String getKey_session(Object login_id) {
return SaTokenManager.getConfig().getTokenName() + ":" + login_key + ":session:" + login_id;
}
}

View File

@@ -0,0 +1,131 @@
package cn.dev33.satoken.stp;
import java.util.Map;
import org.springframework.stereotype.Service;
import cn.dev33.satoken.session.SaSession;
/**
* 一个默认的实现
*/
@Service
public class StpUtil {
// 底层的 StpLogic 对象
public static StpLogic stpLogic = new StpLogic("login");
// =================== 获取token 相关 ===================
/** 获取当前tokenValue */
public static String getTokenValue() {
return stpLogic.getTokenValue();
}
/** 获取指定id的tokenValue */
public static String getTokenValueByLoginId(Object login_id) {
return stpLogic.getTokenValueByLoginId(login_id);
}
/** 获取当前会话的token信息tokenName与tokenValue */
public static Map<String, String> getTokenInfo() {
return stpLogic.getTokenInfo();
}
// =================== 登录相关操作 ===================
/** 在当前会话上设置登录id建议的类型long | int | String */
public static void setLoginId(Object login_id) {
stpLogic.setLoginId(login_id);
}
/** 当前会话注销登录 */
public static void logout() {
stpLogic.logout();
}
/** 指定login_id的会话注销登录踢人下线 */
public static void logoutByLoginId(Object login_id) {
stpLogic.logoutByLoginId(login_id);
}
// 查询相关
/** 获取当前会话是否已经登录 */
public static boolean isLogin() {
return stpLogic.isLogin();
}
/** 获取当前会话登录id, 如果未登录,则抛出异常 */
public static Object getLoginId() {
return stpLogic.getLoginId();
}
/** 获取当前会话登录id, 如果未登录,则返回默认值 */
public static <T> T getLoginId(T default_value) {
return stpLogic.getLoginId(default_value);
}
/** 获取当前会话登录id, 如果未登录则返回null */
public static Object getLoginId_defaultNull() {
return stpLogic.getLoginId_defaultNull();
}
/** 获取当前会话登录id, 并转换为String */
public static String getLoginId_asString() {
return stpLogic.getLoginId_asString();
}
/** 获取当前会话登录id, 并转换为int */
public static int getLoginId_asInt() {
return stpLogic.getLoginId_asInt();
}
/** 获取当前会话登录id, 并转换为long */
public static long getLoginId_asLong() {
return stpLogic.getLoginId_asLong();
}
// =================== session相关 ===================
/** 获取指定login_id的session */
public static SaSession getSessionByLoginId(Object login_id) {
return stpLogic.getSessionByLoginId(login_id);
}
/** 获取当前会话的session */
public static SaSession getSession() {
return stpLogic.getSession();
}
// =================== 权限验证操作 ===================
/** 指定login_id是否含有指定权限 */
public static boolean hasPermission(Object login_id, Object pcode) {
return stpLogic.hasPermission(login_id, pcode);
}
/** 当前会话是否含有指定权限 */
public static boolean hasPermission(Object pcode) {
return stpLogic.hasPermission(pcode);
}
/** 当前账号是否含有指定权限 没有就抛出异常 */
public static void checkPermission(Object pcode) {
stpLogic.checkPermission(pcode);
}
/** 当前账号是否含有指定权限 【指定多个,必须全都有】 */
public static void checkPermissionAnd(Object... pcodeArray) {
stpLogic.checkPermissionAnd(pcodeArray);
}
/** 当前账号是否含有指定权限 【指定多个,有一个就可以了】 */
public static void checkPermissionOr(Object... pcodeArray) {
stpLogic.checkPermissionOr(pcodeArray);
}
}

View File

@@ -0,0 +1,80 @@
package cn.dev33.satoken.util;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* cookie工具类
* @author kong
*
*/
public class SaCookieUtil {
/**
* 获取指定cookie
*/
public static Cookie getCookie(HttpServletRequest request, String cookieName) {
Cookie[] cookies = request.getCookies();
if(cookies != null) {
for(int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
if(cookie != null && cookieName.equals(cookie.getName())) {
return cookie;
}
}
}
return null;
}
/**
* 添加cookie
*/
public static void addCookie(HttpServletResponse response,String name,String value,String path,int timeout) {
Cookie cookie = new Cookie(name, value);
if(path == null) {
path = "/";
}
cookie.setPath(path);
cookie.setMaxAge(timeout);
response.addCookie(cookie);
}
/**
* 删除cookie
*/
public static void delCookie(HttpServletRequest request,HttpServletResponse response,String name) {
Cookie[] cookies = request.getCookies();
if(cookies != null){
for(Cookie cookie : cookies) {
if(cookies != null && (name).equals(cookie.getName())) {
addCookie(response,name,null,null,0);
return;
}
}
}
}
/**
* 修改cookie的value值
*/
public static void updateCookie(HttpServletRequest request,HttpServletResponse response,String name,String value) {
Cookie[] cookies = request.getCookies();
if(cookies != null){
for(Cookie cookie : cookies) {
if(cookies != null && (name).equals(cookie.getName())) {
addCookie(response,name,value,cookie.getPath(),cookie.getMaxAge());
return;
}
}
}
}
}

View File

@@ -0,0 +1,34 @@
package cn.dev33.satoken.util;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
/**
* SpringMVC相关操作
* @author kong
*
*/
public class SpringMVCUtil {
// 获取当前会话的 request
public static HttpServletRequest getRequest() {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();// 大善人SpringMVC提供的封装
if(servletRequestAttributes == null) {
throw new RuntimeException("当前环境非JavaWeb");
}
return servletRequestAttributes.getRequest();
}
// 获取当前会话的
public static HttpServletResponse getResponse() {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();// 大善人SpringMVC提供的封装
if(servletRequestAttributes == null) {
throw new RuntimeException("当前环境非JavaWeb");
}
return servletRequestAttributes.getResponse();
}
}