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

细化未登录异常类型、Cookie操作改为接口代理模式等功能点,为 v1.5.0 版本做准备

上级 81dbf339
......@@ -26,18 +26,18 @@
</dependency>
<!-- 开发测试 -->
<!-- <dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-dev</artifactId>
<version>1.4.0</version>
</dependency> -->
</dependency>
<!-- sa-token 权限认证, 在线文档:http://sa-token.dev33.cn/ -->
<dependency>
<!-- <dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token</artifactId>
<version>1.4.0</version>
</dependency>
</dependency> -->
<!-- SpringBoot整合redis -->
<dependency>
......
......@@ -13,6 +13,7 @@ public class SaTokenDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SaTokenDemoApplication.class, args);
System.out.println("启动成功:sa-token配置如下:" + SaTokenManager.getConfig());
// StpUtil.getSessionByLoginId(10001)
}
......
......@@ -15,7 +15,7 @@ import cn.dev33.satoken.config.SaTokenConfig;
@Configuration
public class MySaTokenConfig implements WebMvcConfigurer {
// 获取配置Bean (以代码的方式配置sa-token)
// 获取配置Bean (以代码的方式配置sa-token, 此配置会覆盖yml中的配置 )
@Primary
@Bean(name="MySaTokenConfig")
public SaTokenConfig getSaTokenConfig() {
......
......@@ -7,7 +7,7 @@ import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
// import org.springframework.stereotype.Component;
import org.springframework.stereotype.Component;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.session.SaSession;
......@@ -15,7 +15,7 @@ import cn.dev33.satoken.session.SaSession;
/**
* sa-token持久层的实现类 , 基于redis
*/
// @Component // 打开此注解,保证此类被springboot扫描,即可完成sa-token与redis的集成
@Component // 打开此注解,保证此类被springboot扫描,即可完成sa-token与redis的集成
public class SaTokenDaoRedis implements SaTokenDao {
......@@ -46,6 +46,16 @@ public class SaTokenDaoRedis implements SaTokenDao {
stringRedisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
}
// 更新指定key-value键值对 (过期时间取原来的值)
@Override
public void updateValue(String key, String value) {
long expire = redisTemplate.getExpire(key);
if(expire == -2) { // -2 = 无此键
return;
}
stringRedisTemplate.opsForValue().set(key, value, expire, TimeUnit.SECONDS);
}
// 删除一个指定的key
@Override
public void delKey(String key) {
......@@ -77,10 +87,13 @@ public class SaTokenDaoRedis implements SaTokenDao {
// 删除一个指定的session
@Override
public void delSaSession(String sessionId) {
public void deleteSaSession(String sessionId) {
redisTemplate.delete(sessionId);
}
......
package com.pj.satoken;
import java.util.Map;
import org.springframework.stereotype.Service;
import cn.dev33.satoken.SaTokenManager;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpLogic;
/**
* 一个默认的实现
* @author kong
*/
@Service
public class StpUserUtil {
/**
* 底层的 StpLogic 对象
*/
public static StpLogic stpLogic = new StpLogic("user") {
@Override
public String getKeyTokenName() {
return SaTokenManager.getConfig().getTokenName() + "-user";
}
};
// =================== 获取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);
}
// 查询相关
/**
* 获取当前会话是否已经登录
* @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);
}
}
......@@ -36,6 +36,20 @@ public class GlobalException {
AjaxJson aj = null;
if (e instanceof NotLoginException) { // 如果是未登录异常
aj = AjaxJson.getNotLogin();
// 判断具体是什么类型
NotLoginException ee = (NotLoginException) e;
if(ee.getType() == NotLoginException.NOT_TOKEN) {
aj.setMsg("未提供token");
}
if(ee.getType() == NotLoginException.INVALID_TOKEN) {
aj.setMsg("token无效");
}
if(ee.getType() == NotLoginException.BE_REPLACED) {
aj.setMsg("token已被顶下线");
}
if(ee.getType() == NotLoginException.TOKEN_TIMEOUT) {
aj.setMsg("token已过期");
}
} else if(e instanceof NotPermissionException) { // 如果是权限异常
NotPermissionException ee = (NotPermissionException) e;
aj = AjaxJson.getNotJur("无此权限:" + ee.getCode());
......
......@@ -112,10 +112,29 @@ public class TestController {
return AjaxJson.getSuccess();
}
// 测试注解式鉴权, 浏览器访问: http://localhost:8081/test/getInfo
@SaCheckLogin // 注解式鉴权:当前会话必须登录才能通过
@RequestMapping("getInfo")
public AjaxJson getInfo() {
return AjaxJson.getSuccessData("用户信息");
}
// 测试 浏览器访问: http://localhost:8081/test/test
@RequestMapping("test")
public AjaxJson test() {
StpUtil.setLoginId(10001);
// System.out.println(StpUtil.getSession().getId());
// System.out.println(StpUserUtil.getSession().getId());
StpUtil.getSessionByLoginId(10001).setAttribute("name", "123");
System.out.println(StpUtil.getSessionByLoginId(10001).getAttribute("name"));
return AjaxJson.getSuccess();
}
}
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.SaCookieOper;
import cn.dev33.satoken.cookie.SaCookieOperDefaultImpl;
import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.dao.SaTokenDaoDefault;
import cn.dev33.satoken.dao.SaTokenDaoDefaultImpl;
import cn.dev33.satoken.stp.StpInterface;
import cn.dev33.satoken.stp.StpInterfaceDefaultImpl;
import cn.dev33.satoken.util.SaTokenInsideUtil;
......@@ -38,7 +42,6 @@ public class SaTokenManager {
}
}
/**
* 持久化 Bean
*/
......@@ -54,11 +57,10 @@ public class SaTokenManager {
}
public synchronized static void initDao() {
if (dao == null) {
setDao(new SaTokenDaoDefault());
setDao(new SaTokenDaoDefaultImpl());
}
}
/**
* 权限认证 Bean
*/
......@@ -78,6 +80,45 @@ public class SaTokenManager {
}
}
/**
* sa-token行为 Bean
*/
public static SaTokenAction sta;
public static SaTokenAction getSta() {
if (sta == null) {
initSta();
}
return sta;
}
public static void setSta(SaTokenAction sta) {
SaTokenManager.sta = sta;
}
public synchronized static void initSta() {
if (sta == null) {
setSta(new SaTokenActionDefaultImpl());
}
}
/**
* sa-token cookie操作 Bean
*/
public static SaCookieOper saCookieOper;
public static SaCookieOper getSaCookieOper() {
if (saCookieOper == null) {
initgetSaCookieOper();
}
return saCookieOper;
}
public static void setSaCookieOper(SaCookieOper saCookieOper) {
SaTokenManager.saCookieOper = saCookieOper;
}
public synchronized static void initgetSaCookieOper() {
if (saCookieOper == null) {
setSaCookieOper(new SaCookieOperDefaultImpl());
}
}
......
package cn.dev33.satoken.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface SaTokenAction {
/**
* 获取当前请求的Request对象
* @return 当前请求的Request对象
*/
public HttpServletRequest getCurrRequest();
/**
* 获取当前会话的 response
* @return
*/
public HttpServletResponse getResponse();
/**
* 生成一个token
* @param loginId 账号id
* @param loginKey 登录标识key
* @return
*/
public String createToken(Object loginId, String loginKey);
}
package cn.dev33.satoken.action;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.dev33.satoken.util.SpringMvcUtil;
/**
* 对 SaTokenAction 接口的默认实现
* @author kong
*
*/
public class SaTokenActionDefaultImpl implements SaTokenAction {
/**
* 获取当前请求的Request对象
*/
@Override
public HttpServletRequest getCurrRequest() {
return SpringMvcUtil.getRequest();
}
/**
* 获取当前请求的Response对象
*/
@Override
public HttpServletResponse getResponse() {
return SpringMvcUtil.getResponse();
}
/**
* 生成一个token
*/
@Override
public String createToken(Object loginId, String loginKey) {
return UUID.randomUUID().toString();
}
}
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 SaCookieOper {
/**
* 获取指定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);
}
package cn.dev33.satoken.cookie;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.dev33.satoken.util.SaCookieUtil;
/**
* sa-token 对cookie的相关操作 接口实现类
* @author kong
*
*/
public class SaCookieOperDefaultImpl implements SaCookieOper {
/**
* 获取指定cookie
*/
public Cookie getCookie(HttpServletRequest request, String cookieName) {
return SaCookieUtil.getCookie(request, cookieName);
}
/**
* 添加cookie
*/
public void addCookie(HttpServletResponse response, String name, String value, String path, int timeout) {
SaCookieUtil.addCookie(response, name, value, path, timeout);
}
/**
* 删除cookie
*/
public void delCookie(HttpServletRequest request, HttpServletResponse response, String name) {
SaCookieUtil.delCookie(request, response, name);
}
/**
* 修改cookie的value值
*/
public void updateCookie(HttpServletRequest request, HttpServletResponse response, String name, String value) {
SaCookieUtil.updateCookie(request, response, name, value);
}
}
......@@ -25,6 +25,13 @@ public interface SaTokenDao {
*/
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 键名称
......@@ -57,7 +64,7 @@ public interface SaTokenDao {
* 删除一个指定的session
* @param sessionId sessionId
*/
public void delSaSession(String sessionId);
public void deleteSaSession(String sessionId);
}
......@@ -10,7 +10,7 @@ import cn.dev33.satoken.session.SaSession;
* @author kong
*
*/
public class SaTokenDaoDefault implements SaTokenDao {
public class SaTokenDaoDefaultImpl implements SaTokenDao {
/**
* 所有数据集合
......@@ -28,6 +28,11 @@ public class SaTokenDaoDefault implements SaTokenDao {
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);
......@@ -50,7 +55,7 @@ public class SaTokenDaoDefault implements SaTokenDao {
}
@Override
public void delSaSession(String sessionId) {
public void deleteSaSession(String sessionId) {
dataMap.remove(sessionId);
}
......
package cn.dev33.satoken.exception;
import cn.dev33.satoken.stp.StpUtil;
import java.util.Arrays;
import java.util.List;
/**
* 没有登陆抛出的异常
......@@ -14,35 +15,76 @@ public class NotLoginException extends RuntimeException {
*/
private static final long serialVersionUID = 6806129545290130142L;
// ------------------- 异常类型常量 --------------------
/*
* 这里简述一下为什么要把常量设计为String类型
* 因为loginId刚取出的时候类型为String,为了避免两者相比较时不必要的类型转换带来的性能消耗,故在此直接将常量类型设计为String
*/
/** 表示未提供token */
public static final String NOT_TOKEN = "-1";
/** 表示token无效 */
public static final String INVALID_TOKEN = "-2";
/** 表示token已被顶下线 */
public static final String BE_REPLACED = "-3";
/** 表示token已过期 */
public static final String TOKEN_TIMEOUT = "-4";
/**
* 代表异常token的标志集合
*/
public static final List<String> ABNORMAL_LIST = Arrays.asList(NOT_TOKEN, INVALID_TOKEN, BE_REPLACED, TOKEN_TIMEOUT);
/**
* login_key
* 异常类型
*/
private String type;
/**
* 获取异常类型
* @return
*/
public String getType() {
return type;
}
/**
* loginKey
*/
private String loginKey;
/**
* 获得login_key
* 获得loginKey
* @return login_key
*/
public String getLoginKey() {
return loginKey;
}
/**
* 创建一个
*/
public NotLoginException() {
this(StpUtil.stpLogic.loginKey);
}
// /**
// * 创建一个
// */
// public NotLoginException() {
// this(StpUtil.stpLogic.loginKey);
// }
/**
* 创建一个
* @param loginKey login_key
*/
public NotLoginException(String loginKey) {
public NotLoginException(String loginKey, String type) {
// 这里到底要不要拼接上login_key呢?纠结
super("当前会话未登录");
this.loginKey = loginKey;
this.type = type;
}
}
......@@ -53,8 +53,8 @@ public class SaSessionCustomUtil {
* 删除指定key的session
* @param sessionId 删除指定key
*/
public static void delSessionById(String sessionId) {
SaTokenManager.getDao().delSaSession(getSessionKey(sessionId));
public static void deleteSessionById(String sessionId) {
SaTokenManager.getDao().deleteSaSession(getSessionKey(sessionId));
}
......
......@@ -3,7 +3,6 @@ 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;
......@@ -14,9 +13,7 @@ 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.SaTokenInsideUtil;
import cn.dev33.satoken.util.SpringMvcUtil;
/**
* sa-token 权限验证,逻辑 实现类
......@@ -42,13 +39,20 @@ public class StpLogic {
// =================== 获取token 相关 ===================
/**
* 返回token名称
* @return 此StpLogic的token名称
*/
public String getTokenName() {
return getKeyTokenName();
}
/**
* 随机生成一个tokenValue
* @return 生成的tokenValue
*/
public String randomTokenValue() {
return UUID.randomUUID().toString();
public String randomTokenValue(Object loginId) {
return SaTokenManager.getSta().createToken(loginId, loginKey);
}
/**
......@@ -57,9 +61,9 @@ public class StpLogic {
*/
public String getTokenValue(){
// 0、获取相应对象
HttpServletRequest request = SpringMvcUtil.getRequest();
HttpServletRequest request = SaTokenManager.getSta().getCurrRequest();
SaTokenConfig config = SaTokenManager.getConfig();
String keyTokenName = getKeyTokenName();
String keyTokenName = getTokenName();
// 1、尝试从request里读取
if(request.getAttribute(SaTokenInsideUtil.JUST_CREATED_SAVE_KEY) != null) {
......@@ -81,7 +85,7 @@ public class StpLogic {
}
// 4、尝试从cookie里读取
if(config.getIsReadCookie() == true){
Cookie cookie = SaCookieUtil.getCookie(request, keyTokenName);
Cookie cookie = SaTokenManager.getSaCookieOper().getCookie(request, keyTokenName);
if(cookie != null){
String tokenValue = cookie.getValue();
if(tokenValue != null) {
......@@ -108,7 +112,7 @@ public class StpLogic {
*/
public Map<String, String> getTokenInfo() {
Map<String, String> map = new HashMap<String, String>();
map.put("tokenName", getKeyTokenName());
map.put("tokenName", getTokenName());
map.put("tokenValue", getTokenValue());
return map;
}
......@@ -123,19 +127,20 @@ public class StpLogic {
public void setLoginId(Object loginId) {
// 1、获取相应对象
HttpServletRequest request = SpringMvcUtil.getRequest();
HttpServletRequest request = SaTokenManager.getSta().getCurrRequest();
SaTokenConfig config = SaTokenManager.getConfig();
SaTokenDao dao = SaTokenManager.getDao();
// 2、获取tokenValue
String tokenValue = getTokenValueByLoginId(loginId); // 获取旧tokenValue
if(tokenValue == null){ // 为null则创建一个新的
tokenValue = randomTokenValue();
tokenValue = randomTokenValue(loginId);
} else {
// 不为null, 并且配置不共享,则删掉原来,并且创建新的
// 不为null, 并且配置不共享,则:将原来的标记为[被顶替]
if(config.getIsShare() == false){
dao.delKey(getKeyTokenValue(tokenValue));
tokenValue = randomTokenValue();
// dao.delKey(getKeyTokenValue(tokenValue));
dao.updateValue(getKeyTokenValue(tokenValue), NotLoginException.BE_REPLACED);
tokenValue = randomTokenValue(loginId);
}
}
......@@ -144,7 +149,7 @@ public class StpLogic {
dao.setValue(getKeyLoginId(loginId), tokenValue, config.getTimeout()); // uid -> token
request.setAttribute(SaTokenInsideUtil.JUST_CREATED_SAVE_KEY, tokenValue); // 保存到本次request里
if(config.getIsReadCookie() == true){
SaCookieUtil.addCookie(SpringMvcUtil.getResponse(), getKeyTokenName(), tokenValue, "/", (int)config.getTimeout()); // cookie注入
SaTokenManager.getSaCookieOper().addCookie(SaTokenManager.getSta().getResponse(), getTokenName(), tokenValue, "/", (int)config.getTimeout()); // cookie注入
}
}
......@@ -152,14 +157,27 @@ public class StpLogic {
* 当前会话注销登录
*/
public void logout() {
Object loginId = getLoginIdDefaultNull();
if(loginId != null) {
logoutByLoginId(loginId);
// 清除cookie
if(SaTokenManager.getConfig().getIsReadCookie() == true){
SaCookieUtil.delCookie(SpringMvcUtil.getRequest(), SpringMvcUtil.getResponse(), getKeyTokenName());
}
// 如果连token都没有,那么无需执行任何操作
String tokenValue = getTokenValue();
if(tokenValue == null) {
return;
}
// 如果打开了cookie模式,第一步,先把cookie清除掉
if(SaTokenManager.getConfig().getIsReadCookie() == true){
SaTokenManager.getSaCookieOper().delCookie(SaTokenManager.getSta().getCurrRequest(), SaTokenManager.getSta().getResponse(), getTokenName());
}
// 尝试从db中获取loginId值
String loginId = SaTokenManager.getDao().getValue(getKeyTokenValue(tokenValue));
// 如果根本查不到loginId,那么也无需执行任何操作
if(loginId == null) {
return;
}
// 如果已经被顶替或已过期,那么只删除此token即可
if(loginId.equals(NotLoginException.BE_REPLACED) || loginId.equals(NotLoginException.TOKEN_TIMEOUT)) {
return;
}
// 至此,已经是一个正常的loginId,开始三清
logoutByLoginId(loginId);
}
/**
......@@ -178,7 +196,6 @@ public class StpLogic {
SaTokenManager.getDao().delKey(getKeyTokenValue(tokenValue)); // 清除token-id键值对
SaTokenManager.getDao().delKey(getKeyLoginId(loginId)); // 清除id-token键值对
SaTokenManager.getDao().delKey(getKeySession(loginId)); // 清除其session
// SaCookieUtil.delCookie(SpringMVCUtil.getRequest(), SpringMVCUtil.getResponse(), getKey_tokenName()); // 清除cookie
}
// 查询相关
......@@ -188,6 +205,7 @@ public class StpLogic {
* @return 是否已登录
*/
public boolean isLogin() {
// 判断条件:不为null,并且不在异常项集合里
return getLoginIdDefaultNull() != null;
}
......@@ -203,10 +221,25 @@ public class StpLogic {
* @return .
*/
public Object getLoginId() {
Object loginId = getLoginIdDefaultNull();
// 如果获取不到token,则抛出:无token
String tokenValue = getTokenValue();
if(tokenValue == null) {
throw new NotLoginException(loginKey, NotLoginException.NOT_TOKEN);
}
// 查找此token对应loginId, 则抛出:无效token
String loginId = SaTokenManager.getDao().getValue(getKeyTokenValue(tokenValue));
if(loginId == null) {
throw new NotLoginException(this.loginKey);
throw new NotLoginException(loginKey, NotLoginException.INVALID_TOKEN);
}
// 如果是已经被顶替下去了, 则抛出:已被顶下线
if(loginId.equals(NotLoginException.BE_REPLACED)) {
throw new NotLoginException(loginKey, NotLoginException.BE_REPLACED);
}
// 如果是已经过期,则抛出已经过期
if(loginId.equals(NotLoginException.TOKEN_TIMEOUT)) {
throw new NotLoginException(loginKey, NotLoginException.TOKEN_TIMEOUT);
}
// 至此,返回loginId
return loginId;
}
......@@ -218,9 +251,11 @@ public class StpLogic {
@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());
}
......@@ -235,17 +270,21 @@ public class StpLogic {
/**
* 获取当前会话登录id, 如果未登录,则返回null
* @return
* @return .
*/
public Object getLoginIdDefaultNull() {
String tokenValue = getTokenValue();
if(tokenValue != null) {
Object loginId = SaTokenManager.getDao().getValue(getKeyTokenValue(tokenValue));
if(loginId != null) {
return loginId;
}
// 如果连token都是空的,则直接返回
String tokenValue = getTokenValue();
if(tokenValue == null) {
return null;
}
return null;
// loginId为null或者在异常项里面,均视为未登录
Object loginId = SaTokenManager.getDao().getValue(getKeyTokenValue(tokenValue));
if(loginId == null || NotLoginException.ABNORMAL_LIST.contains(loginId)) {
return null;
}
// 执行到此,证明loginId已经是个正常的账号id了
return loginId;
}
/**
......@@ -328,7 +367,7 @@ public class StpLogic {
* @return .
*/
public SaSession getSessionByLoginId(Object loginId) {
return getSessionByLoginId(getKeySession(loginId), false);
return getSessionByLoginId(loginId, true);
}
/**
......@@ -336,7 +375,7 @@ public class StpLogic {
* @return
*/
public SaSession getSession() {
return getSessionBySessionId(getKeySession(getLoginId()), true);
return getSessionByLoginId(getLoginId());
}
......
......@@ -21,6 +21,13 @@ public class StpUtil {
// =================== 获取token 相关 ===================
/**
* 返回token名称
* @return 此StpLogic的token名称
*/
public static String getTokenName() {
return stpLogic.getTokenName();
}
/**
* 获取当前tokenValue
......
......@@ -4,92 +4,90 @@ import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* cookie工具类
* cookie操作工具类
*
* @author kong
*
*/
public class SaCookieUtil {
/**
* 获取指定cookie .
* @param request .
*
* @param request .
* @param cookieName .
* @return .
*/
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;
}
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(cookies != null && (name).equals(cookie.getName())) {
addCookie(response,name,null,null,0);
return;
}
}
}
}
/**
* 添加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(cookies != null && (name).equals(cookie.getName())) {
addCookie(response,name,value,cookie.getPath(),cookie.getMaxAge());
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;
}
}
}
}
}
\ No newline at end of file
......@@ -19,7 +19,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;
......@@ -29,7 +28,7 @@ import cn.dev33.satoken.session.SaSession;
/**
* sa-token持久层的实现类 , 基于redis
*/
@Component // 保证此类被springboot扫描,即可完成sa-token与redis的集成
@Component // 打开此注解,保证此类被springboot扫描,即可完成sa-token与redis的集成
public class SaTokenDaoRedis implements SaTokenDao {
......@@ -42,10 +41,8 @@ public class SaTokenDaoRedis implements SaTokenDao {
@Autowired
@SuppressWarnings({ "rawtypes", "unchecked" })
public void setRedisTemplate(RedisTemplate redisTemplate) {
RedisSerializer stringSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringSerializer);
JdkSerializationRedisSerializer jrSerializer = new JdkSerializationRedisSerializer();
redisTemplate.setValueSerializer(jrSerializer);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
this.redisTemplate = redisTemplate;
}
......@@ -62,6 +59,16 @@ public class SaTokenDaoRedis implements SaTokenDao {
stringRedisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
}
// 更新指定key-value键值对 (过期时间取原来的值)
@Override
public void updateValue(String key, String value) {
long expire = redisTemplate.getExpire(key);
if(expire == -2) { // -2 = 无此键
return;
}
stringRedisTemplate.opsForValue().set(key, value, expire, TimeUnit.SECONDS);
}
// 删除一个指定的key
@Override
public void delKey(String key) {
......@@ -93,12 +100,10 @@ public class SaTokenDaoRedis implements SaTokenDao {
// 删除一个指定的session
@Override
public void delSaSession(String sessionId) {
public void deleteSaSession(String sessionId) {
redisTemplate.delete(sessionId);
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册