mirror of
https://gitee.com/dromara/sa-token.git
synced 2026-02-27 16:50:24 +08:00
⚡ 重构为maven多模块架构
This commit is contained in:
12
sp-token-core/.gitignore
vendored
Normal file
12
sp-token-core/.gitignore
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
target/
|
||||
|
||||
node_modules/
|
||||
bin/
|
||||
.settings/
|
||||
unpackage/
|
||||
.classpath
|
||||
.project
|
||||
|
||||
.factorypath
|
||||
|
||||
.idea/
|
||||
28
sp-token-core/pom.xml
Normal file
28
sp-token-core/pom.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-parent</artifactId>
|
||||
<version>1.6.0</version>
|
||||
</parent>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>sa-token-core</name>
|
||||
<artifactId>sa-token-core</artifactId>
|
||||
<description>A Java Web lightweight authority authentication framework, comprehensive function, easy to use</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>3.1.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
|
||||
</project>
|
||||
149
sp-token-core/src/main/java/cn/dev33/satoken/SaTokenManager.java
Normal file
149
sp-token-core/src/main/java/cn/dev33/satoken/SaTokenManager.java
Normal file
@@ -0,0 +1,149 @@
|
||||
package cn.dev33.satoken;
|
||||
|
||||
import cn.dev33.satoken.action.SaTokenAction;
|
||||
import cn.dev33.satoken.action.SaTokenActionDefaultImpl;
|
||||
import cn.dev33.satoken.config.SaTokenConfig;
|
||||
import cn.dev33.satoken.config.SaTokenConfigFactory;
|
||||
import cn.dev33.satoken.cookie.SaTokenCookie;
|
||||
import cn.dev33.satoken.cookie.SaTokenCookieDefaultImpl;
|
||||
import cn.dev33.satoken.dao.SaTokenDao;
|
||||
import cn.dev33.satoken.dao.SaTokenDaoDefaultImpl;
|
||||
import cn.dev33.satoken.servlet.SaTokenServlet;
|
||||
import cn.dev33.satoken.servlet.SaTokenServletDefaultImpl;
|
||||
import cn.dev33.satoken.stp.StpInterface;
|
||||
import cn.dev33.satoken.stp.StpInterfaceDefaultImpl;
|
||||
import cn.dev33.satoken.util.SaTokenInsideUtil;
|
||||
|
||||
/**
|
||||
* 管理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()) {
|
||||
SaTokenInsideUtil.printSaToken();
|
||||
}
|
||||
}
|
||||
public synchronized static void initConfig() {
|
||||
if (config == null) {
|
||||
setConfig(SaTokenConfigFactory.createConfig());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 持久化 Bean
|
||||
*/
|
||||
public static SaTokenDao saTokenDao;
|
||||
public static SaTokenDao getSaTokenDao() {
|
||||
if (saTokenDao == null) {
|
||||
initSaTokenDao();
|
||||
}
|
||||
return saTokenDao;
|
||||
}
|
||||
public static void setSaTokenDao(SaTokenDao saTokenDao) {
|
||||
SaTokenManager.saTokenDao = saTokenDao;
|
||||
}
|
||||
public synchronized static void initSaTokenDao() {
|
||||
if (saTokenDao == null) {
|
||||
setSaTokenDao(new SaTokenDaoDefaultImpl());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 权限认证 Bean
|
||||
*/
|
||||
public static StpInterface stpInterface;
|
||||
public static StpInterface getStpInterface() {
|
||||
if (stpInterface == null) {
|
||||
initStpInterface();
|
||||
}
|
||||
return stpInterface;
|
||||
}
|
||||
public static void setStpInterface(StpInterface stpInterface) {
|
||||
SaTokenManager.stpInterface = stpInterface;
|
||||
}
|
||||
public synchronized static void initStpInterface() {
|
||||
if (stpInterface == null) {
|
||||
setStpInterface(new StpInterfaceDefaultImpl());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 框架行为 Bean
|
||||
*/
|
||||
public static SaTokenAction saTokenAction;
|
||||
public static SaTokenAction getSaTokenAction() {
|
||||
if (saTokenAction == null) {
|
||||
initSaTokenAction();
|
||||
}
|
||||
return saTokenAction;
|
||||
}
|
||||
public static void setSaTokenAction(SaTokenAction saTokenAction) {
|
||||
SaTokenManager.saTokenAction = saTokenAction;
|
||||
}
|
||||
public synchronized static void initSaTokenAction() {
|
||||
if (saTokenAction == null) {
|
||||
setSaTokenAction(new SaTokenActionDefaultImpl());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cookie操作 Bean
|
||||
*/
|
||||
public static SaTokenCookie saTokenCookie;
|
||||
public static SaTokenCookie getSaTokenCookie() {
|
||||
if (saTokenCookie == null) {
|
||||
initSaTokenCookie();
|
||||
}
|
||||
return saTokenCookie;
|
||||
}
|
||||
public static void setSaTokenCookie(SaTokenCookie saTokenCookie) {
|
||||
SaTokenManager.saTokenCookie = saTokenCookie;
|
||||
}
|
||||
public synchronized static void initSaTokenCookie() {
|
||||
if (saTokenCookie == null) {
|
||||
setSaTokenCookie(new SaTokenCookieDefaultImpl());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Servlet操作 Bean
|
||||
*/
|
||||
public static SaTokenServlet saTokenServlet;
|
||||
public static SaTokenServlet getSaTokenServlet() {
|
||||
if (saTokenServlet == null) {
|
||||
initSaTokenServlet();
|
||||
}
|
||||
return saTokenServlet;
|
||||
}
|
||||
public static void setSaTokenServlet(SaTokenServlet saTokenServlet) {
|
||||
SaTokenManager.saTokenServlet = saTokenServlet;
|
||||
}
|
||||
public synchronized static void initSaTokenServlet() {
|
||||
if (saTokenServlet == null) {
|
||||
setSaTokenServlet(new SaTokenServletDefaultImpl());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package cn.dev33.satoken.action;
|
||||
|
||||
public interface SaTokenAction {
|
||||
|
||||
|
||||
/**
|
||||
* 生成一个token
|
||||
* @param loginId 账号id
|
||||
* @param loginKey 登录标识key
|
||||
* @return 一个token
|
||||
*/
|
||||
public String createToken(Object loginId, String loginKey);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package cn.dev33.satoken.action;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import cn.dev33.satoken.SaTokenManager;
|
||||
import cn.dev33.satoken.util.SaTokenInsideUtil;
|
||||
|
||||
/**
|
||||
* 对 SaTokenAction 接口的默认实现
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaTokenActionDefaultImpl implements SaTokenAction {
|
||||
|
||||
|
||||
/**
|
||||
* 生成一个token
|
||||
*/
|
||||
@Override
|
||||
public String createToken(Object loginId, String loginKey) {
|
||||
// 生成各种花式token
|
||||
String tokenStyle = SaTokenManager.getConfig().getTokenStyle();
|
||||
// uuid
|
||||
if(tokenStyle.equals("uuid")) {
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
// 简单uuid (不带下划线)
|
||||
else if(tokenStyle.equals("simple-uuid")) {
|
||||
return UUID.randomUUID().toString().replaceAll("-", "");
|
||||
}
|
||||
// 32位随机字符串
|
||||
else if(tokenStyle.equals("random-32")) {
|
||||
return SaTokenInsideUtil.getRandomString(32);
|
||||
}
|
||||
// 64位随机字符串
|
||||
else if(tokenStyle.equals("random-64")) {
|
||||
return SaTokenInsideUtil.getRandomString(64);
|
||||
}
|
||||
// 128位随机字符串
|
||||
else if(tokenStyle.equals("random-128")) {
|
||||
return SaTokenInsideUtil.getRandomString(128);
|
||||
}
|
||||
// tik风格
|
||||
else if(tokenStyle.equals("tik")) {
|
||||
return SaTokenInsideUtil.getRandomString(2) + "_" + SaTokenInsideUtil.getRandomString(14) + "_" + SaTokenInsideUtil.getRandomString(16) + "__";
|
||||
}
|
||||
// 默认
|
||||
else {
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package cn.dev33.satoken.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 标注一个路由方法,当前会话必须已登录才能通过
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.METHOD, ElementType.TYPE })
|
||||
public @interface SaCheckLogin {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package cn.dev33.satoken.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 标注一个路由方法,当前会话必须具有指定权限才可以通过
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD,ElementType.TYPE})
|
||||
public @interface SaCheckPermission {
|
||||
|
||||
/**
|
||||
* 权限码数组 ,String类型
|
||||
* @return .
|
||||
*/
|
||||
String [] value() default {};
|
||||
|
||||
/**
|
||||
* 权限码数组 ,int类型
|
||||
* @return .
|
||||
*/
|
||||
int [] valueInt() default {};
|
||||
|
||||
/**
|
||||
* 权限码数组 ,long类型
|
||||
* @return .
|
||||
*/
|
||||
long [] valueLong() default {};
|
||||
|
||||
/**
|
||||
* 是否属于and型验证 ,true=必须全部具有,false=只要具有一个就可以通过
|
||||
* @return .
|
||||
*/
|
||||
boolean isAnd() default true;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
package cn.dev33.satoken.config;
|
||||
|
||||
/**
|
||||
* sa-token 总配置类
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaTokenConfig {
|
||||
|
||||
private String tokenName = "satoken"; // token名称 (同时也是cookie名称)
|
||||
private long timeout = 30 * 24 * 60 * 60; // token有效期,单位s 默认30天
|
||||
private Boolean isShare = true; // 在多人登录同一账号时,是否共享会话 (为true时共用一个,为false时新登录挤掉旧登录)
|
||||
private Boolean isReadBody = true; // 是否尝试从请求体里读取token
|
||||
private Boolean isReadHead = true; // 是否尝试从header里读取token
|
||||
private Boolean isReadCookie = true; // 是否尝试从cookie里读取token
|
||||
private String tokenStyle = "uuid"; // token风格
|
||||
|
||||
private Boolean isV = true; // 是否在初始化配置时打印版本字符画
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return tokenName
|
||||
*/
|
||||
public String getTokenName() {
|
||||
return tokenName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tokenName 要设置的 tokenName
|
||||
*/
|
||||
public void setTokenName(String tokenName) {
|
||||
this.tokenName = tokenName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return timeout
|
||||
*/
|
||||
public long getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param timeout 要设置的 timeout
|
||||
*/
|
||||
public void setTimeout(long timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return isShare
|
||||
*/
|
||||
public Boolean getIsShare() {
|
||||
return isShare;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isShare 要设置的 isShare
|
||||
*/
|
||||
public void setIsShare(Boolean isShare) {
|
||||
this.isShare = isShare;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return isReadCookie
|
||||
*/
|
||||
public Boolean getIsReadCookie() {
|
||||
return isReadCookie;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isReadCookie 要设置的 isReadCookie
|
||||
*/
|
||||
public void setIsReadCookie(Boolean isReadCookie) {
|
||||
this.isReadCookie = isReadCookie;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return isReadHead
|
||||
*/
|
||||
public Boolean getIsReadHead() {
|
||||
return isReadHead;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isReadHead 要设置的 isReadHead
|
||||
*/
|
||||
public void setIsReadHead(Boolean isReadHead) {
|
||||
this.isReadHead = isReadHead;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return isReadBody
|
||||
*/
|
||||
public Boolean getIsReadBody() {
|
||||
return isReadBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isReadBody 要设置的 isReadBody
|
||||
*/
|
||||
public void setIsReadBody(Boolean isReadBody) {
|
||||
this.isReadBody = isReadBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return tokenStyle
|
||||
*/
|
||||
public String getTokenStyle() {
|
||||
return tokenStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tokenStyle 要设置的 tokenStyle
|
||||
*/
|
||||
public void setTokenStyle(String tokenStyle) {
|
||||
this.tokenStyle = tokenStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return isV
|
||||
*/
|
||||
public Boolean getIsV() {
|
||||
return isV;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isV 要设置的 isV
|
||||
*/
|
||||
public void setIsV(Boolean isV) {
|
||||
this.isV = isV;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SaTokenConfig [tokenName=" + tokenName + ", timeout=" + timeout + ", isShare=" + isShare
|
||||
+ ", isReadBody=" + isReadBody + ", isReadHead=" + isReadHead + ", isReadCookie=" + isReadCookie
|
||||
+ ", tokenStyle=" + tokenStyle + ", isV=" + isV + "]";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* 创建一个配置文件
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
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<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()) {
|
||||
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 e) {
|
||||
throw new RuntimeException("属性赋值出错:" + field.getName(), e);
|
||||
} catch (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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package cn.dev33.satoken.cookie;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* sa-token 对cookie的相关操作 接口类
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public interface SaTokenCookie {
|
||||
|
||||
/**
|
||||
* 获取指定cookie .
|
||||
*
|
||||
* @param request .
|
||||
* @param cookieName .
|
||||
* @return .
|
||||
*/
|
||||
public Cookie getCookie(HttpServletRequest request, String cookieName);
|
||||
|
||||
/**
|
||||
* 添加cookie
|
||||
*
|
||||
* @param response .
|
||||
* @param name .
|
||||
* @param value .
|
||||
* @param path .
|
||||
* @param timeout .
|
||||
*/
|
||||
public void addCookie(HttpServletResponse response, String name, String value, String path, int timeout);
|
||||
|
||||
/**
|
||||
* 删除cookie .
|
||||
*
|
||||
* @param request .
|
||||
* @param response .
|
||||
* @param name .
|
||||
*/
|
||||
public void delCookie(HttpServletRequest request, HttpServletResponse response, String name);
|
||||
|
||||
/**
|
||||
* 修改cookie的value值
|
||||
*
|
||||
* @param request .
|
||||
* @param response .
|
||||
* @param name .
|
||||
* @param value .
|
||||
*/
|
||||
public void updateCookie(HttpServletRequest request, HttpServletResponse response, String name, String value);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package cn.dev33.satoken.cookie;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* sa-token 对cookie的相关操作 接口实现类
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaTokenCookieDefaultImpl implements SaTokenCookie {
|
||||
|
||||
/**
|
||||
* 获取指定cookie
|
||||
*/
|
||||
public Cookie getCookie(HttpServletRequest request, String cookieName) {
|
||||
return SaTokenCookieUtil.getCookie(request, cookieName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加cookie
|
||||
*/
|
||||
public void addCookie(HttpServletResponse response, String name, String value, String path, int timeout) {
|
||||
SaTokenCookieUtil.addCookie(response, name, value, path, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除cookie
|
||||
*/
|
||||
public void delCookie(HttpServletRequest request, HttpServletResponse response, String name) {
|
||||
SaTokenCookieUtil.delCookie(request, response, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改cookie的value值
|
||||
*/
|
||||
public void updateCookie(HttpServletRequest request, HttpServletResponse response, String name, String value) {
|
||||
SaTokenCookieUtil.updateCookie(request, response, name, value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package cn.dev33.satoken.cookie;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* cookie操作工具类
|
||||
*
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaTokenCookieUtil {
|
||||
|
||||
/**
|
||||
* 获取指定cookie .
|
||||
*
|
||||
* @param request .
|
||||
* @param cookieName .
|
||||
* @return .
|
||||
*/
|
||||
public static Cookie getCookie(HttpServletRequest request, String cookieName) {
|
||||
Cookie[] cookies = request.getCookies();
|
||||
if (cookies != null) {
|
||||
for (Cookie cookie : cookies) {
|
||||
if (cookie != null && cookieName.equals(cookie.getName())) {
|
||||
return cookie;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加cookie
|
||||
*
|
||||
* @param response .
|
||||
* @param name .
|
||||
* @param value .
|
||||
* @param path .
|
||||
* @param timeout .
|
||||
*/
|
||||
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 .
|
||||
*
|
||||
* @param request .
|
||||
* @param response .
|
||||
* @param name .
|
||||
*/
|
||||
public static void delCookie(HttpServletRequest request, HttpServletResponse response, String name) {
|
||||
Cookie[] cookies = request.getCookies();
|
||||
if (cookies != null) {
|
||||
for (Cookie cookie : cookies) {
|
||||
if (cookie != null && (name).equals(cookie.getName())) {
|
||||
addCookie(response, name, null, null, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改cookie的value值
|
||||
*
|
||||
* @param request .
|
||||
* @param response .
|
||||
* @param name .
|
||||
* @param 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 (cookie != null && (name).equals(cookie.getName())) {
|
||||
addCookie(response, name, value, cookie.getPath(), cookie.getMaxAge());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package cn.dev33.satoken.dao;
|
||||
|
||||
import cn.dev33.satoken.session.SaSession;
|
||||
|
||||
/**
|
||||
* sa-token持久层的接口
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public interface SaTokenDao {
|
||||
|
||||
|
||||
/**
|
||||
* 根据key获取value ,如果没有,则返回空
|
||||
* @param key 键名称
|
||||
* @return value
|
||||
*/
|
||||
public String getValue(String key);
|
||||
|
||||
/**
|
||||
* 写入指定key-value键值对,并设定过期时间 (单位:秒)
|
||||
* @param key 键名称
|
||||
* @param value 值
|
||||
* @param timeout 过期时间,单位:s
|
||||
*/
|
||||
public void setValue(String key, String value, long timeout);
|
||||
|
||||
/**
|
||||
* 修改指定key-value键值对 (过期时间取原来的值)
|
||||
* @param key 键名称
|
||||
* @param value 值
|
||||
*/
|
||||
public void updateValue(String key, String value);
|
||||
|
||||
/**
|
||||
* 删除一个指定的key
|
||||
* @param key 键名称
|
||||
*/
|
||||
public void delKey(String key);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 根据指定key的session,如果没有,则返回空
|
||||
* @param sessionId 键名称
|
||||
* @return SaSession
|
||||
*/
|
||||
public SaSession getSaSession(String sessionId);
|
||||
|
||||
/**
|
||||
* 将指定session持久化
|
||||
* @param session 要保存的session对象
|
||||
* @param timeout 过期时间,单位: s
|
||||
*/
|
||||
public void saveSaSession(SaSession session, long timeout);
|
||||
|
||||
/**
|
||||
* 更新指定session
|
||||
* @param session 要更新的session对象
|
||||
*/
|
||||
public void updateSaSession(SaSession session);
|
||||
|
||||
/**
|
||||
* 删除一个指定的session
|
||||
* @param sessionId sessionId
|
||||
*/
|
||||
public void deleteSaSession(String sessionId);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package cn.dev33.satoken.dao;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import cn.dev33.satoken.session.SaSession;
|
||||
|
||||
/**
|
||||
* sa-token持久层默认的实现类 , 基于内存Map
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaTokenDaoDefaultImpl 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 updateValue(String key, String value) {
|
||||
this.setValue(key, value, 0);
|
||||
}
|
||||
|
||||
@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 deleteSaSession(String sessionId) {
|
||||
dataMap.remove(sessionId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package cn.dev33.satoken.exception;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 没有登陆抛出的异常
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class NotLoginException extends RuntimeException {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 6806129545290130142L;
|
||||
|
||||
|
||||
// ------------------- 异常类型常量 --------------------
|
||||
|
||||
/*
|
||||
* 这里简述一下为什么要把常量设计为String类型
|
||||
* 因为loginId刚取出的时候类型为String,为了避免两者相比较时不必要的类型转换带来的性能消耗,故在此直接将常量类型设计为String
|
||||
*/
|
||||
|
||||
/** 表示未提供token */
|
||||
public static final String NOT_TOKEN = "-1";
|
||||
public static final String NOT_TOKEN_MESSAGE = "未提供token";
|
||||
|
||||
/** 表示token无效 */
|
||||
public static final String INVALID_TOKEN = "-2";
|
||||
public static final String INVALID_TOKEN_MESSAGE = "token无效";
|
||||
|
||||
/** 表示token已过期 */
|
||||
public static final String TOKEN_TIMEOUT = "-3";
|
||||
public static final String TOKEN_TIMEOUT_MESSAGE = "token已过期";
|
||||
|
||||
/** 表示token已被顶下线 */
|
||||
public static final String BE_REPLACED = "-4";
|
||||
public static final String BE_REPLACED_MESSAGE = "token已被顶下线";
|
||||
|
||||
/** 表示token已被踢下线 */
|
||||
public static final String KICK_OUT = "-5";
|
||||
public static final String KICK_OUT_MESSAGE = "token已被踢下线";
|
||||
|
||||
/** 默认的提示语 */
|
||||
public static final String DEFAULT_MESSAGE = "当前会话未登录";
|
||||
|
||||
|
||||
/**
|
||||
* 代表异常token的标志集合
|
||||
*/
|
||||
public static final List<String> ABNORMAL_LIST = Arrays.asList(NOT_TOKEN, INVALID_TOKEN, TOKEN_TIMEOUT, BE_REPLACED, KICK_OUT);
|
||||
|
||||
|
||||
/**
|
||||
* 异常类型
|
||||
*/
|
||||
private String type;
|
||||
/**
|
||||
* 获取异常类型
|
||||
* @return
|
||||
*/
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* loginKey
|
||||
*/
|
||||
private String loginKey;
|
||||
/**
|
||||
* 获得loginKey
|
||||
* @return login_key
|
||||
*/
|
||||
public String getLoginKey() {
|
||||
return loginKey;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// /**
|
||||
// * 创建一个
|
||||
// */
|
||||
// public NotLoginException() {
|
||||
// this(StpUtil.stpLogic.loginKey);
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* 创建一个
|
||||
* @param message 异常消息
|
||||
* @param loginKey loginKey
|
||||
* @param type 类型
|
||||
*/
|
||||
public NotLoginException(String message, String loginKey, String type) {
|
||||
// 这里到底要不要拼接上login_key呢?纠结
|
||||
super(message);
|
||||
this.loginKey = loginKey;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* 静态方法构建一个NotLoginException
|
||||
* @param loginKey loginKey
|
||||
* @param type 场景类型
|
||||
* @return 构建完毕的异常对象
|
||||
*/
|
||||
public static NotLoginException newInstance(String loginKey, String type) {
|
||||
String message = null;
|
||||
if(type.equals(NOT_TOKEN)) {
|
||||
message = NOT_TOKEN_MESSAGE;
|
||||
}
|
||||
else if(type.equals(INVALID_TOKEN)) {
|
||||
message = INVALID_TOKEN_MESSAGE;
|
||||
}
|
||||
else if(type.equals(TOKEN_TIMEOUT)) {
|
||||
message = TOKEN_TIMEOUT_MESSAGE;
|
||||
}
|
||||
else if(type.equals(BE_REPLACED)) {
|
||||
message = BE_REPLACED_MESSAGE;
|
||||
}
|
||||
else if(type.equals(KICK_OUT)) {
|
||||
message = KICK_OUT_MESSAGE;
|
||||
}
|
||||
else {
|
||||
message = DEFAULT_MESSAGE;
|
||||
}
|
||||
return new NotLoginException(message, loginKey, type);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package cn.dev33.satoken.exception;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
|
||||
/**
|
||||
* 没有指定权限码,抛出的异常
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class NotPermissionException extends RuntimeException {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 6806129545290130142L;
|
||||
|
||||
/**
|
||||
* 权限码
|
||||
*/
|
||||
private Object code;
|
||||
/**
|
||||
* @return 获得权限码
|
||||
*/
|
||||
public Object getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* login_key
|
||||
*/
|
||||
private String loginKey;
|
||||
/**
|
||||
* 获得login_key
|
||||
* @return login_key
|
||||
*/
|
||||
public String getLoginKey() {
|
||||
return loginKey;
|
||||
}
|
||||
|
||||
|
||||
public NotPermissionException(Object code) {
|
||||
this(code, StpUtil.stpLogic.loginKey);
|
||||
}
|
||||
public NotPermissionException(Object code, String loginKey) {
|
||||
// 这里到底要不要拼接上login_key呢?纠结
|
||||
super("无此权限:" + code);
|
||||
this.code = code;
|
||||
this.loginKey = loginKey;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package cn.dev33.satoken.exception;
|
||||
|
||||
/**
|
||||
* sa-token框架内部逻辑发生错误抛出的异常
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaTokenException extends RuntimeException {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 6806129545290130132L;
|
||||
|
||||
|
||||
public SaTokenException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package cn.dev33.satoken.servlet;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* Servlet相关操作
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public interface SaTokenServlet {
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前请求的Request对象
|
||||
* @return 当前请求的Request对象
|
||||
*/
|
||||
public HttpServletRequest getRequest();
|
||||
|
||||
/**
|
||||
* 获取当前会话的 response
|
||||
* @return 当前请求的response
|
||||
*/
|
||||
public HttpServletResponse getResponse();
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package cn.dev33.satoken.servlet;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* sa-token 对Servlet的相关操作 接口默认实现类
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaTokenServletDefaultImpl implements SaTokenServlet {
|
||||
|
||||
/**
|
||||
* 获取当前请求的Request对象
|
||||
*/
|
||||
@Override
|
||||
public HttpServletRequest getRequest() {
|
||||
throw new RuntimeException("请实现SaTokenServlet接口后进行Servlet相关操作");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前请求的Response对象
|
||||
*/
|
||||
@Override
|
||||
public HttpServletResponse getResponse() {
|
||||
throw new RuntimeException("请实现SaTokenServlet接口后进行Servlet相关操作");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* 会话id
|
||||
*/
|
||||
private String id;
|
||||
/**
|
||||
* 当前会话创建时间
|
||||
*/
|
||||
private long createTime;
|
||||
/**
|
||||
* 当前会话键值对
|
||||
*/
|
||||
private Map<String, Object> dataMap;
|
||||
|
||||
|
||||
/**
|
||||
* 构建一个 session对象
|
||||
* @param id sessionId
|
||||
*/
|
||||
public SaSession(String id) {
|
||||
this.id = id;
|
||||
this.createTime = System.currentTimeMillis();
|
||||
this.dataMap = new HashMap<String, Object>();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会话id
|
||||
* @return id
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回当前会话创建时间
|
||||
* @return 时间戳
|
||||
*/
|
||||
public long getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入一个值
|
||||
* @param key 名称
|
||||
* @param value 值
|
||||
*/
|
||||
public void setAttribute(String key, Object value) {
|
||||
dataMap.put(key, value);
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
* 取出一个值
|
||||
* @param key 名称
|
||||
* @return 值
|
||||
*/
|
||||
public Object getAttribute(String key) {
|
||||
return dataMap.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取值,并指定取不到值时的默认值
|
||||
* @param key 名称
|
||||
* @param defaultValue 取不到值的时候返回的默认值
|
||||
* @return value
|
||||
*/
|
||||
public Object getAttribute(String key, Object defaultValue) {
|
||||
Object value = getAttribute(key);
|
||||
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 是否含有
|
||||
*/
|
||||
public boolean containsAttribute(String key) {
|
||||
return dataMap.keySet().contains(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回当前session会话所有key
|
||||
* @return 所有值的key列表
|
||||
*/
|
||||
public Set<String> getAttributeKeys() {
|
||||
return dataMap.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据集合(如果更新map里的值,请调用session.update()方法避免数据过时 )
|
||||
* @return 返回底层储存值的map对象
|
||||
*/
|
||||
public Map<String, Object> getDataMap() {
|
||||
return dataMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将这个session从持久库更新一下
|
||||
*/
|
||||
public void update() {
|
||||
SaTokenManager.getSaTokenDao().updateSaSession(this);
|
||||
}
|
||||
|
||||
|
||||
// /** 注销会话(注销后,此session会话将不再存储服务器上) */
|
||||
// public void logout() {
|
||||
// SaTokenManager.getDao().delSaSession(this.id);
|
||||
// }
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package cn.dev33.satoken.session;
|
||||
|
||||
import cn.dev33.satoken.SaTokenManager;
|
||||
|
||||
/**
|
||||
* 自定义sa-session工具类
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaSessionCustomUtil {
|
||||
|
||||
/**
|
||||
* 添加上指定前缀,防止恶意伪造session
|
||||
*/
|
||||
public static String session_key = "custom";
|
||||
public static String getSessionKey(String sessionId) {
|
||||
return SaTokenManager.getConfig().getTokenName() + ":" + session_key + ":session:" + sessionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定key的session是否存在
|
||||
* @param sessionId session的id
|
||||
* @return 是否存在
|
||||
*/
|
||||
public boolean isExists(String sessionId) {
|
||||
return SaTokenManager.getSaTokenDao().getSaSession(getSessionKey(sessionId)) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定key的session
|
||||
* @param sessionId key
|
||||
* @param isCreate 如果没有,是否新建并返回
|
||||
* @return SaSession
|
||||
*/
|
||||
public static SaSession getSessionById(String sessionId, boolean isCreate) {
|
||||
SaSession session = SaTokenManager.getSaTokenDao().getSaSession(getSessionKey(sessionId));
|
||||
if(session == null && isCreate) {
|
||||
session = new SaSession(getSessionKey(sessionId));
|
||||
SaTokenManager.getSaTokenDao().saveSaSession(session, SaTokenManager.getConfig().getTimeout());
|
||||
}
|
||||
return session;
|
||||
}
|
||||
/**
|
||||
* 获取指定key的session, 如果没有则新建并返回
|
||||
* @param sessionId key
|
||||
* @return session对象
|
||||
*/
|
||||
public static SaSession getSessionById(String sessionId) {
|
||||
return getSessionById(sessionId, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除指定key的session
|
||||
* @param sessionId 删除指定key
|
||||
*/
|
||||
public static void deleteSessionById(String sessionId) {
|
||||
SaTokenManager.getSaTokenDao().deleteSaSession(getSessionKey(sessionId));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package cn.dev33.satoken.stp;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 开放权限验证接口,方便重写
|
||||
* @author kong
|
||||
*/
|
||||
public interface StpInterface {
|
||||
|
||||
/**
|
||||
* 返回指定login_id所拥有的权限码集合
|
||||
* @param loginId 账号id
|
||||
* @param loginKey 具体的stp标识
|
||||
* @return .
|
||||
*/
|
||||
public List<Object> getPermissionCodeList(Object loginId, String loginKey);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package cn.dev33.satoken.stp;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 权限验证接口 ,默认实现
|
||||
* @author kong
|
||||
*/
|
||||
public class StpInterfaceDefaultImpl implements StpInterface {
|
||||
|
||||
@Override
|
||||
public List<Object> getPermissionCodeList(Object loginId, String loginKey) {
|
||||
return new ArrayList<Object>();
|
||||
}
|
||||
|
||||
}
|
||||
505
sp-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java
Normal file
505
sp-token-core/src/main/java/cn/dev33/satoken/stp/StpLogic.java
Normal file
@@ -0,0 +1,505 @@
|
||||
package cn.dev33.satoken.stp;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import cn.dev33.satoken.SaTokenManager;
|
||||
import cn.dev33.satoken.config.SaTokenConfig;
|
||||
import cn.dev33.satoken.dao.SaTokenDao;
|
||||
import cn.dev33.satoken.exception.NotLoginException;
|
||||
import cn.dev33.satoken.exception.NotPermissionException;
|
||||
import cn.dev33.satoken.session.SaSession;
|
||||
import cn.dev33.satoken.util.SaTokenInsideUtil;
|
||||
|
||||
/**
|
||||
* sa-token 权限验证,逻辑 实现类
|
||||
* <p>
|
||||
* (stp = sa-token-permission 的缩写 )
|
||||
* @author kong
|
||||
*/
|
||||
public class StpLogic {
|
||||
|
||||
/**
|
||||
* 持久化的key前缀,多账号体系时以此值区分,比如:login、user、admin
|
||||
*/
|
||||
public String loginKey = "";
|
||||
|
||||
/**
|
||||
* 初始化StpLogic, 并制定loginKey
|
||||
* @param loginKey .
|
||||
*/
|
||||
public StpLogic(String loginKey) {
|
||||
this.loginKey = loginKey;
|
||||
}
|
||||
|
||||
|
||||
// =================== 获取token 相关 ===================
|
||||
|
||||
/**
|
||||
* 返回token名称
|
||||
* @return 此StpLogic的token名称
|
||||
*/
|
||||
public String getTokenName() {
|
||||
return getKeyTokenName();
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机生成一个tokenValue
|
||||
* @param loginId loginId
|
||||
* @return 生成的tokenValue
|
||||
*/
|
||||
public String randomTokenValue(Object loginId) {
|
||||
return SaTokenManager.getSaTokenAction().createToken(loginId, loginKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前tokenValue
|
||||
* @return 当前tokenValue
|
||||
*/
|
||||
public String getTokenValue(){
|
||||
// 0、获取相应对象
|
||||
HttpServletRequest request = SaTokenManager.getSaTokenServlet().getRequest();
|
||||
SaTokenConfig config = SaTokenManager.getConfig();
|
||||
String keyTokenName = getTokenName();
|
||||
|
||||
// 1、尝试从request里读取
|
||||
if(request.getAttribute(SaTokenInsideUtil.JUST_CREATED_SAVE_KEY) != null) {
|
||||
return String.valueOf(request.getAttribute(SaTokenInsideUtil.JUST_CREATED_SAVE_KEY));
|
||||
}
|
||||
// 2、尝试从请求体里面读取
|
||||
if(config.getIsReadBody() == true){
|
||||
String tokenValue = request.getParameter(keyTokenName);
|
||||
if(tokenValue != null) {
|
||||
return tokenValue;
|
||||
}
|
||||
}
|
||||
// 3、尝试从header力读取
|
||||
if(config.getIsReadHead() == true){
|
||||
String tokenValue = request.getHeader(keyTokenName);
|
||||
if(tokenValue != null) {
|
||||
return tokenValue;
|
||||
}
|
||||
}
|
||||
// 4、尝试从cookie里读取
|
||||
if(config.getIsReadCookie() == true){
|
||||
Cookie cookie = SaTokenManager.getSaTokenCookie().getCookie(request, keyTokenName);
|
||||
if(cookie != null){
|
||||
String tokenValue = cookie.getValue();
|
||||
if(tokenValue != null) {
|
||||
return tokenValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 5、都读取不到,那算了吧还是
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定id的tokenValue
|
||||
* @param loginId .
|
||||
* @return .
|
||||
*/
|
||||
public String getTokenValueByLoginId(Object loginId) {
|
||||
return SaTokenManager.getSaTokenDao().getValue(getKeyLoginId(loginId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前会话的token信息:tokenName与tokenValue
|
||||
* @return 一个Map对象
|
||||
*/
|
||||
public Map<String, String> getTokenInfo() {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put("tokenName", getTokenName());
|
||||
map.put("tokenValue", getTokenValue());
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
// =================== 登录相关操作 ===================
|
||||
|
||||
/**
|
||||
* 在当前会话上登录id
|
||||
* @param loginId 登录id ,建议的类型:(long | int | String)
|
||||
*/
|
||||
public void setLoginId(Object loginId) {
|
||||
|
||||
// 1、获取相应对象
|
||||
HttpServletRequest request = SaTokenManager.getSaTokenServlet().getRequest();
|
||||
SaTokenConfig config = SaTokenManager.getConfig();
|
||||
SaTokenDao dao = SaTokenManager.getSaTokenDao();
|
||||
|
||||
// 2、获取tokenValue
|
||||
String tokenValue = getTokenValueByLoginId(loginId); // 获取旧tokenValue
|
||||
if(tokenValue == null){ // 为null则创建一个新的
|
||||
tokenValue = randomTokenValue(loginId);
|
||||
} else {
|
||||
// 不为null, 并且配置不共享,则:将原来的标记为[被顶替]
|
||||
if(config.getIsShare() == false){
|
||||
// dao.delKey(getKeyTokenValue(tokenValue));
|
||||
dao.updateValue(getKeyTokenValue(tokenValue), NotLoginException.BE_REPLACED);
|
||||
tokenValue = randomTokenValue(loginId);
|
||||
}
|
||||
}
|
||||
|
||||
// 3、持久化
|
||||
dao.setValue(getKeyTokenValue(tokenValue), String.valueOf(loginId), config.getTimeout()); // token -> uid
|
||||
dao.setValue(getKeyLoginId(loginId), tokenValue, config.getTimeout()); // uid -> token
|
||||
request.setAttribute(SaTokenInsideUtil.JUST_CREATED_SAVE_KEY, tokenValue); // 保存到本次request里
|
||||
if(config.getIsReadCookie() == true){
|
||||
SaTokenManager.getSaTokenCookie().addCookie(SaTokenManager.getSaTokenServlet().getResponse(), getTokenName(), tokenValue, "/", (int)config.getTimeout()); // cookie注入
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前会话注销登录
|
||||
*/
|
||||
public void logout() {
|
||||
// 如果连token都没有,那么无需执行任何操作
|
||||
String tokenValue = getTokenValue();
|
||||
if(tokenValue == null) {
|
||||
return;
|
||||
}
|
||||
// 如果打开了cookie模式,第一步,先把cookie清除掉
|
||||
if(SaTokenManager.getConfig().getIsReadCookie() == true){
|
||||
SaTokenManager.getSaTokenCookie().delCookie(SaTokenManager.getSaTokenServlet().getRequest(), SaTokenManager.getSaTokenServlet().getResponse(), getTokenName());
|
||||
}
|
||||
// 尝试从db中获取loginId值
|
||||
String loginId = SaTokenManager.getSaTokenDao().getValue(getKeyTokenValue(tokenValue));
|
||||
// 如果根本查不到loginId,那么也无需执行任何操作
|
||||
if(loginId == null) {
|
||||
return;
|
||||
}
|
||||
// 如果已过期或被顶替或被挤下线,那么只删除此token即可
|
||||
if(loginId.equals(NotLoginException.TOKEN_TIMEOUT) || loginId.equals(NotLoginException.BE_REPLACED) || loginId.equals(NotLoginException.KICK_OUT)) {
|
||||
return;
|
||||
}
|
||||
// 至此,已经是一个正常的loginId,开始三清
|
||||
logoutByLoginId(loginId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定loginId的会话注销登录(清退下线)
|
||||
* @param loginId 账号id
|
||||
*/
|
||||
public void logoutByLoginId(Object loginId) {
|
||||
|
||||
// 获取相应tokenValue
|
||||
String tokenValue = getTokenValueByLoginId(loginId);
|
||||
if(tokenValue == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 清除相关数据
|
||||
SaTokenManager.getSaTokenDao().delKey(getKeyTokenValue(tokenValue)); // 清除token-id键值对
|
||||
SaTokenManager.getSaTokenDao().delKey(getKeyLoginId(loginId)); // 清除id-token键值对
|
||||
SaTokenManager.getSaTokenDao().deleteSaSession(getKeySession(loginId)); // 清除其session
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定loginId的会话注销登录(踢人下线)
|
||||
* @param loginId 账号id
|
||||
*/
|
||||
public void kickoutByLoginId(Object loginId) {
|
||||
|
||||
// 获取相应tokenValue
|
||||
String tokenValue = getTokenValueByLoginId(loginId);
|
||||
if(tokenValue == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 清除相关数据
|
||||
SaTokenManager.getSaTokenDao().updateValue(getKeyTokenValue(tokenValue), NotLoginException.KICK_OUT); // 标记:已被踢下线
|
||||
SaTokenManager.getSaTokenDao().delKey(getKeyLoginId(loginId)); // 清除id-token键值对
|
||||
SaTokenManager.getSaTokenDao().deleteSaSession(getKeySession(loginId)); // 清除其session
|
||||
}
|
||||
|
||||
// 查询相关
|
||||
|
||||
/**
|
||||
* 获取当前会话是否已经登录
|
||||
* @return 是否已登录
|
||||
*/
|
||||
public boolean isLogin() {
|
||||
// 判断条件:不为null,并且不在异常项集合里
|
||||
return getLoginIdDefaultNull() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检验当前会话是否已经登录,如未登录,则抛出异常
|
||||
*/
|
||||
public void checkLogin() {
|
||||
getLoginId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前会话登录id, 如果未登录,则抛出异常
|
||||
* @return .
|
||||
*/
|
||||
public Object getLoginId() {
|
||||
// 如果获取不到token,则抛出:无token
|
||||
String tokenValue = getTokenValue();
|
||||
if(tokenValue == null) {
|
||||
throw NotLoginException.newInstance(loginKey, NotLoginException.NOT_TOKEN);
|
||||
}
|
||||
// 查找此token对应loginId, 则抛出:无效token
|
||||
String loginId = SaTokenManager.getSaTokenDao().getValue(getKeyTokenValue(tokenValue));
|
||||
if(loginId == null) {
|
||||
throw NotLoginException.newInstance(loginKey, NotLoginException.INVALID_TOKEN);
|
||||
}
|
||||
// 如果是已经过期,则抛出已经过期
|
||||
if(loginId.equals(NotLoginException.TOKEN_TIMEOUT)) {
|
||||
throw NotLoginException.newInstance(loginKey, NotLoginException.TOKEN_TIMEOUT);
|
||||
}
|
||||
// 如果是已经被顶替下去了, 则抛出:已被顶下线
|
||||
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);
|
||||
}
|
||||
// 至此,返回loginId
|
||||
return loginId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前会话登录id, 如果未登录,则返回默认值
|
||||
* @param defaultValue .
|
||||
* @return .
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T>T getLoginId(T defaultValue) {
|
||||
Object loginId = getLoginIdDefaultNull();
|
||||
// 如果loginId为null,则返回默认值
|
||||
if(loginId == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
// 开始尝试类型转换,只尝试三种类型:int、long、String
|
||||
if(defaultValue instanceof Integer) {
|
||||
return (T)Integer.valueOf(loginId.toString());
|
||||
}
|
||||
if(defaultValue instanceof Long) {
|
||||
return (T)Long.valueOf(loginId.toString());
|
||||
}
|
||||
if(defaultValue instanceof String) {
|
||||
return (T)loginId.toString();
|
||||
}
|
||||
return (T)loginId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前会话登录id, 如果未登录,则返回null
|
||||
* @return .
|
||||
*/
|
||||
public Object getLoginIdDefaultNull() {
|
||||
// 如果连token都是空的,则直接返回
|
||||
String tokenValue = getTokenValue();
|
||||
if(tokenValue == null) {
|
||||
return null;
|
||||
}
|
||||
// loginId为null或者在异常项里面,均视为未登录
|
||||
Object loginId = SaTokenManager.getSaTokenDao().getValue(getKeyTokenValue(tokenValue));
|
||||
if(loginId == null || NotLoginException.ABNORMAL_LIST.contains(loginId)) {
|
||||
return null;
|
||||
}
|
||||
// 执行到此,证明loginId已经是个正常的账号id了
|
||||
return loginId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前会话登录id, 并转换为String
|
||||
* @return
|
||||
*/
|
||||
public String getLoginIdAsString() {
|
||||
return String.valueOf(getLoginId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前会话登录id, 并转换为int
|
||||
* @return .
|
||||
*/
|
||||
public int getLoginIdAsInt() {
|
||||
// Object loginId = getLoginId();
|
||||
// if(loginId instanceof Integer) {
|
||||
// return (Integer)loginId;
|
||||
// }
|
||||
return Integer.valueOf(String.valueOf(getLoginId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前会话登录id, 并转换为long
|
||||
* @return .
|
||||
*/
|
||||
public long getLoginIdAsLong() {
|
||||
// Object loginId = getLoginId();
|
||||
// if(loginId instanceof Long) {
|
||||
// return (Long)loginId;
|
||||
// }
|
||||
return Long.valueOf(String.valueOf(getLoginId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定token对应的登录id,如果未登录,则返回 null
|
||||
* @return .
|
||||
*/
|
||||
public Object getLoginIdByToken(String tokenValue) {
|
||||
if(tokenValue != null) {
|
||||
Object loginId = SaTokenManager.getSaTokenDao().getValue(getKeyTokenValue(tokenValue));
|
||||
if(loginId != null) {
|
||||
return loginId;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// =================== session相关 ===================
|
||||
|
||||
/**
|
||||
* 获取指定key的session, 如果没有,isCreate=是否新建并返回
|
||||
* @param sessionId .
|
||||
* @param isCreate .
|
||||
* @return .
|
||||
*/
|
||||
protected SaSession getSessionBySessionId(String sessionId, boolean isCreate) {
|
||||
SaSession session = SaTokenManager.getSaTokenDao().getSaSession(sessionId);
|
||||
if(session == null && isCreate) {
|
||||
session = new SaSession(sessionId);
|
||||
SaTokenManager.getSaTokenDao().saveSaSession(session, SaTokenManager.getConfig().getTimeout());
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定loginId的session, 如果没有,isCreate=是否新建并返回
|
||||
* @param loginId 登录id
|
||||
* @param isCreate 是否新建
|
||||
* @return SaSession
|
||||
*/
|
||||
public SaSession getSessionByLoginId(Object loginId, boolean isCreate) {
|
||||
return getSessionBySessionId(getKeySession(loginId), isCreate);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定loginId的session
|
||||
* @param loginId .
|
||||
* @return .
|
||||
*/
|
||||
public SaSession getSessionByLoginId(Object loginId) {
|
||||
return getSessionByLoginId(loginId, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前会话的session
|
||||
* @return
|
||||
*/
|
||||
public SaSession getSession() {
|
||||
return getSessionByLoginId(getLoginId());
|
||||
}
|
||||
|
||||
|
||||
|
||||
// =================== 权限验证操作 ===================
|
||||
|
||||
/**
|
||||
* 指定loginId是否含有指定权限
|
||||
* @param loginId .
|
||||
* @param pcode .
|
||||
* @return .
|
||||
*/
|
||||
public boolean hasPermission(Object loginId, Object pcode) {
|
||||
List<Object> pcodeList = SaTokenManager.getStpInterface().getPermissionCodeList(loginId, loginKey);
|
||||
return !(pcodeList == null || pcodeList.contains(pcode) == false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前会话是否含有指定权限
|
||||
* @param pcode .
|
||||
* @return .
|
||||
*/
|
||||
public boolean hasPermission(Object pcode) {
|
||||
return hasPermission(getLoginId(), pcode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前账号是否含有指定权限 , 没有就抛出异常
|
||||
* @param pcode .
|
||||
*/
|
||||
public void checkPermission(Object pcode) {
|
||||
if(hasPermission(pcode) == false) {
|
||||
throw new NotPermissionException(pcode, this.loginKey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前账号是否含有指定权限 , 【指定多个,必须全都有】
|
||||
* @param pcodeArray .
|
||||
*/
|
||||
public void checkPermissionAnd(Object... pcodeArray){
|
||||
Object loginId = getLoginId();
|
||||
List<Object> pcodeList = SaTokenManager.getStpInterface().getPermissionCodeList(loginId, loginKey);
|
||||
for (Object pcode : pcodeArray) {
|
||||
if(pcodeList.contains(pcode) == false) {
|
||||
throw new NotPermissionException(pcode, this.loginKey); // 没有权限抛出异常
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前账号是否含有指定权限 , 【指定多个,有一个就可以了】
|
||||
* @param pcodeArray .
|
||||
*/
|
||||
public void checkPermissionOr(Object... pcodeArray){
|
||||
Object loginId = getLoginId();
|
||||
List<Object> pcodeList = SaTokenManager.getStpInterface().getPermissionCodeList(loginId, loginKey);
|
||||
for (Object pcode : pcodeArray) {
|
||||
if(pcodeList.contains(pcode) == true) {
|
||||
return; // 有的话提前退出
|
||||
}
|
||||
}
|
||||
if(pcodeArray.length > 0) {
|
||||
throw new NotPermissionException(pcodeArray[0], this.loginKey); // 没有权限抛出异常
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// =================== 返回相应key ===================
|
||||
|
||||
/**
|
||||
* 获取key:客户端 tokenName
|
||||
* @return
|
||||
*/
|
||||
public String getKeyTokenName() {
|
||||
return SaTokenManager.getConfig().getTokenName();
|
||||
}
|
||||
/**
|
||||
* 获取key: tokenValue 持久化
|
||||
* @param tokenValue .
|
||||
* @return
|
||||
*/
|
||||
public String getKeyTokenValue(String tokenValue) {
|
||||
return SaTokenManager.getConfig().getTokenName() + ":" + loginKey + ":token:" + tokenValue;
|
||||
}
|
||||
/**
|
||||
* 获取key: id 持久化
|
||||
* @param loginId .
|
||||
* @return
|
||||
*/
|
||||
public String getKeyLoginId(Object loginId) {
|
||||
return SaTokenManager.getConfig().getTokenName() + ":" + loginKey + ":id:" + loginId;
|
||||
}
|
||||
/**
|
||||
* 获取key: session 持久化
|
||||
* @param loginId .
|
||||
* @return .
|
||||
*/
|
||||
public String getKeySession(Object loginId) {
|
||||
return SaTokenManager.getConfig().getTokenName() + ":" + loginKey + ":session:" + loginId;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
236
sp-token-core/src/main/java/cn/dev33/satoken/stp/StpUtil.java
Normal file
236
sp-token-core/src/main/java/cn/dev33/satoken/stp/StpUtil.java
Normal file
@@ -0,0 +1,236 @@
|
||||
package cn.dev33.satoken.stp;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import cn.dev33.satoken.session.SaSession;
|
||||
|
||||
/**
|
||||
* 一个默认的实现
|
||||
* @author kong
|
||||
*/
|
||||
public class StpUtil {
|
||||
|
||||
/**
|
||||
* 底层的 StpLogic 对象
|
||||
*/
|
||||
public static StpLogic stpLogic = new StpLogic("login");
|
||||
|
||||
|
||||
// =================== 获取token 相关 ===================
|
||||
|
||||
/**
|
||||
* 返回token名称
|
||||
* @return 此StpLogic的token名称
|
||||
*/
|
||||
public static String getTokenName() {
|
||||
return stpLogic.getTokenName();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前tokenValue
|
||||
* @return 当前tokenValue
|
||||
*/
|
||||
public static String getTokenValue() {
|
||||
return stpLogic.getTokenValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定id的tokenValue
|
||||
* @param loginId .
|
||||
* @return
|
||||
*/
|
||||
public static String getTokenValueByLoginId(Object loginId) {
|
||||
return stpLogic.getTokenValueByLoginId(loginId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前会话的token信息:tokenName与tokenValue
|
||||
* @return 一个Map对象
|
||||
*/
|
||||
public static Map<String, String> getTokenInfo() {
|
||||
return stpLogic.getTokenInfo();
|
||||
}
|
||||
|
||||
// =================== 登录相关操作 ===================
|
||||
|
||||
/**
|
||||
* 在当前会话上登录id
|
||||
* @param loginId 登录id ,建议的类型:(long | int | String)
|
||||
*/
|
||||
public static void setLoginId(Object loginId) {
|
||||
stpLogic.setLoginId(loginId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前会话注销登录
|
||||
*/
|
||||
public static void logout() {
|
||||
stpLogic.logout();
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定loginId的会话注销登录(清退下线)
|
||||
* @param loginId 账号id
|
||||
*/
|
||||
public static void logoutByLoginId(Object loginId) {
|
||||
stpLogic.logoutByLoginId(loginId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定loginId的会话注销登录(踢人下线)
|
||||
* @param loginId 账号id
|
||||
*/
|
||||
public static void kickoutByLoginId(Object loginId) {
|
||||
stpLogic.kickoutByLoginId(loginId);
|
||||
}
|
||||
|
||||
// 查询相关
|
||||
|
||||
/**
|
||||
* 获取当前会话是否已经登录
|
||||
* @return 是否已登录
|
||||
*/
|
||||
public static boolean isLogin() {
|
||||
return stpLogic.isLogin();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检验当前会话是否已经登录,如未登录,则抛出异常
|
||||
*/
|
||||
public static void checkLogin() {
|
||||
getLoginId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前会话登录id, 如果未登录,则抛出异常
|
||||
* @return .
|
||||
*/
|
||||
public static Object getLoginId() {
|
||||
return stpLogic.getLoginId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前会话登录id, 如果未登录,则返回默认值
|
||||
* @param defaultValue .
|
||||
* @return .
|
||||
*/
|
||||
public static <T> T getLoginId(T defaultValue) {
|
||||
return stpLogic.getLoginId(defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前会话登录id, 如果未登录,则返回null
|
||||
* @return
|
||||
*/
|
||||
public static Object getLoginIdDefaultNull() {
|
||||
return stpLogic.getLoginIdDefaultNull();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前会话登录id, 并转换为String
|
||||
* @return
|
||||
*/
|
||||
public static String getLoginIdAsString() {
|
||||
return stpLogic.getLoginIdAsString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前会话登录id, 并转换为int
|
||||
* @return
|
||||
*/
|
||||
public static int getLoginIdAsInt() {
|
||||
return stpLogic.getLoginIdAsInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前会话登录id, 并转换为long
|
||||
* @return
|
||||
*/
|
||||
public static long getLoginIdAsLong() {
|
||||
return stpLogic.getLoginIdAsLong();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定token对应的登录id,如果未登录,则返回 null
|
||||
* @return .
|
||||
*/
|
||||
public static Object getLoginIdByToken(String tokenValue) {
|
||||
return stpLogic.getLoginIdByToken(tokenValue);
|
||||
}
|
||||
|
||||
// =================== session相关 ===================
|
||||
|
||||
/**
|
||||
* 获取指定loginId的session, 如果没有,isCreate=是否新建并返回
|
||||
* @param loginId 登录id
|
||||
* @param isCreate 是否新建
|
||||
* @return SaSession
|
||||
*/
|
||||
public static SaSession getSessionByLoginId(Object loginId, boolean isCreate) {
|
||||
return stpLogic.getSessionByLoginId(loginId, isCreate);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定loginId的session
|
||||
* @param loginId .
|
||||
* @return .
|
||||
*/
|
||||
public static SaSession getSessionByLoginId(Object loginId) {
|
||||
return stpLogic.getSessionByLoginId(loginId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前会话的session
|
||||
* @return
|
||||
*/
|
||||
public static SaSession getSession() {
|
||||
return stpLogic.getSession();
|
||||
}
|
||||
|
||||
// =================== 权限验证操作 ===================
|
||||
|
||||
/**
|
||||
* 指定loginId是否含有指定权限
|
||||
* @param loginId .
|
||||
* @param pcode .
|
||||
* @return .
|
||||
*/
|
||||
public static boolean hasPermission(Object loginId, Object pcode) {
|
||||
return stpLogic.hasPermission(loginId, pcode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前会话是否含有指定权限
|
||||
* @param pcode .
|
||||
* @return .
|
||||
*/
|
||||
public static boolean hasPermission(Object pcode) {
|
||||
return stpLogic.hasPermission(pcode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前账号是否含有指定权限 , 没有就抛出异常
|
||||
* @param pcode .
|
||||
*/
|
||||
public static void checkPermission(Object pcode) {
|
||||
stpLogic.checkPermission(pcode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前账号是否含有指定权限 , 【指定多个,必须全都有】
|
||||
* @param pcodeArray .
|
||||
*/
|
||||
public static void checkPermissionAnd(Object... pcodeArray) {
|
||||
stpLogic.checkPermissionAnd(pcodeArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前账号是否含有指定权限 , 【指定多个,有一个就可以了】
|
||||
* @param pcodeArray .
|
||||
*/
|
||||
public static void checkPermissionOr(Object... pcodeArray) {
|
||||
stpLogic.checkPermissionOr(pcodeArray);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package cn.dev33.satoken.util;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* sa-token 工具类
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
public class SaTokenInsideUtil {
|
||||
|
||||
|
||||
/**
|
||||
* sa-token 版本号
|
||||
*/
|
||||
public static final String VERSION_NO = "v1.6.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_NO + " \r\n" +
|
||||
"GitHub:" + GITHUB_URL; // + "\r\n";
|
||||
System.out.println(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果token为本次请求新创建的,则以此字符串为key存储在当前request中 JUST_CREATED_SAVE_KEY
|
||||
*/
|
||||
public static final String JUST_CREATED_SAVE_KEY = "JUST_CREATED_SAVE_KEY_";
|
||||
|
||||
/**
|
||||
* 生成指定长度的随机字符串
|
||||
* @param length 字符串的长度
|
||||
* @return 一个随机字符串
|
||||
*/
|
||||
public static String getRandomString(int length) {
|
||||
String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
Random random = new Random();
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = 0; i < length; i++) {
|
||||
int number = random.nextInt(62);
|
||||
sb.append(str.charAt(number));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user