| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549 |
- package jnpf.util;
- import cn.dev33.satoken.same.SaSameUtil;
- import cn.dev33.satoken.session.SaSession;
- import cn.dev33.satoken.session.SaTerminalInfo;
- import cn.dev33.satoken.stp.StpUtil;
- import cn.dev33.satoken.stp.parameter.SaLoginParameter;
- import cn.hutool.core.text.StrPool;
- import jnpf.base.UserInfo;
- import jnpf.consts.DeviceType;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.stereotype.Component;
- import org.springframework.util.ObjectUtils;
- import java.util.List;
- import java.util.stream.Collectors;
- import static jnpf.consts.AuthConsts.TOKEN_PREFIX_SP;
- /**
- * @author JNPF开发平台组
- * @version V3.1.0
- * @copyright 引迈信息技术有限公司
- * @date 2021/3/16 10:57
- */
- @Slf4j
- @Component
- public class UserProvider {
- private static RedisUtil redisUtil;
- private static CacheKeyUtil cacheKeyUtil;
- public static final String USER_INFO_KEY = "userInfo";
- private static final ThreadLocal<UserInfo> USER_CACHE = new ThreadLocal<>();
- public UserProvider(RedisUtil redisUtil, CacheKeyUtil cacheKeyUtil) {
- UserProvider.redisUtil = redisUtil;
- UserProvider.cacheKeyUtil = cacheKeyUtil;
- }
- // =================== 登录相关操作 ===================
- /**
- * 登录系统 适用于Request环境
- *
- * @param userInfo 登录用户信息
- */
- public static void login(UserInfo userInfo) {
- setLocalLoginUser(userInfo);
- StpUtil.login(splicingLoginId(userInfo.getUserId()));
- userInfo.setToken(StpUtil.getTokenValueNotCut());
- userInfo.setSecurityKey(DesUtil.aesOrDecode(TicketUtil.createTicket(userInfo.getToken(), 10*24*60*60000L), true, true));
- setLoginUser(userInfo);
- }
- /**
- * 登录系统 适用于Request环境
- *
- * @param userInfo 用户信息
- * @param loginModel 登录参数
- */
- public static void login(UserInfo userInfo, SaLoginParameter loginModel) {
- setLocalLoginUser(userInfo);
- StpUtil.login(splicingLoginId(userInfo.getUserId()), loginModel);
- userInfo.setToken(StpUtil.getTokenValueNotCut());
- userInfo.setSecurityKey(DesUtil.aesOrDecode(TicketUtil.createTicket(userInfo.getToken(), 10*24*60*60000L), true, true));
- setLoginUser(userInfo);
- }
- /**
- * 适用于非Request环境
- * @param userInfo
- * @param loginModel
- */
- public static void loginNoRequest(UserInfo userInfo, SaLoginParameter loginModel) {
- setLocalLoginUser(userInfo);
- String token = StpUtil.createLoginSession(splicingLoginId(userInfo.getUserId()), loginModel);
- userInfo.setToken(TOKEN_PREFIX_SP + token);
- setLoginUser(userInfo);
- }
- // =================== 登录用户ID相关操作 ===================
- /**
- * 获取指定TOKEN用户ID
- *
- * @param token
- * @return
- */
- public static String getLoginUserId(String token) {
- String loginId = (String) StpUtil.getLoginIdByToken(token);
- return parseLoginId(loginId);
- }
- /**
- * 获取当前用户ID, 包含临时切换用户ID
- *
- * @return
- */
- public static String getLoginUserId() {
- String loginId = getUser().getUserId();
- return parseLoginId(loginId);
- }
- // =================== 用户ID拼接相关操作 ===================
- /**
- * 拼接租户下的用户ID
- *
- * @param userId
- * @return
- */
- public static String splicingLoginId(String userId) {
- return splicingLoginId(userId, null);
- }
- /**
- * 拼接租户下的用户ID
- * @param userId
- * @param tenantId
- * @return
- */
- private static String splicingLoginId(String userId, String tenantId) {
- if(StringUtil.isEmpty(tenantId)){
- tenantId = TenantHolder.getDatasourceId();
- }
- if (!StringUtil.isEmpty(tenantId)) {
- return tenantId + StrPool.COLON + userId;
- }
- return userId;
- }
- /**
- * 解析租户下的登录ID
- * @param loginId
- * @return
- */
- private static String parseLoginId(String loginId) {
- if (loginId != null && loginId.contains(StrPool.COLON)) {
- loginId = loginId.substring(loginId.indexOf(StrPool.COLON) + 1);
- }
- return loginId;
- }
- /**
- * Token是否有效
- *
- * @param token
- * @return
- */
- public static Boolean isValidToken(String token) {
- UserInfo userInfo = getUser(token);
- return userInfo.getUserId() != null;
- }
- // =================== UserInfo缓存相关操作 ===================
- /**
- * 设置Redis用户数据
- */
- public static void setLoginUser(UserInfo userInfo) {
- StpUtil.getTokenSessionByToken(cutToken(userInfo.getToken())).set(USER_INFO_KEY, userInfo);
- }
- /**
- * 设置本地用户数据
- */
- public static void setLocalLoginUser(UserInfo userInfo) {
- USER_CACHE.set(userInfo);
- }
- /**
- * 获取本地用户数据
- */
- public static UserInfo getLocalLoginUser() {
- return USER_CACHE.get();
- }
- /**
- * 清空本地用户数据
- */
- public static void clearLocalUser() {
- USER_CACHE.remove();
- }
- /**
- * 获取用户缓存
- * 保留旧方法
- *
- * @param token
- * @return
- */
- public UserInfo get(String token) {
- return UserProvider.getUser(token);
- }
- /**
- * 获取用户缓存
- *
- * @return
- */
- public UserInfo get() {
- return UserProvider.getUser();
- }
- /**
- * 根据用户ID, 租户ID获取随机获取一个UserInfo
- * @param userId
- * @param tenantId
- * @return
- */
- public static UserInfo getUser(String userId, String tenantId){
- return getUser(userId, tenantId, null, null);
- }
- /**
- * 根据用户ID, 租户ID, 设备类型获取随机获取一个UserInfo
- * @param userId
- * @param tenantId
- * @param includeDevice 指定的设备类型中查找
- * @param excludeDevice 排除指定设备类型
- * @return
- */
- public static UserInfo getUser(String userId, String tenantId, List<String> includeDevice, List<String> excludeDevice){
- SaSession session = StpUtil.getSessionByLoginId(splicingLoginId(userId, tenantId), false);
- if (session != null) {
- List<SaTerminalInfo> tokenSignList = session.getTerminalList();
- if (!tokenSignList.isEmpty()) {
- tokenSignList = tokenSignList.stream().filter(tokenSign -> {
- if(!ObjectUtils.isEmpty(excludeDevice)){
- if(excludeDevice.contains(tokenSign.getDeviceType())){
- return false;
- }
- }
- if(!ObjectUtils.isEmpty(includeDevice)){
- if(!includeDevice.contains(tokenSign.getDeviceType())){
- return false;
- }
- }
- return true;
- }).collect(Collectors.toList());
- if(!tokenSignList.isEmpty()){
- return getUser(tokenSignList.get(0).getTokenValue());
- }
- }
- }
- return new UserInfo();
- }
- /**
- * 获取用户缓存
- *
- * @param token
- * @return
- */
- public static UserInfo getUser(String token) {
- UserInfo userInfo = null;
- String tokens = null;
- if (token != null) {
- tokens = cutToken(token);
- } else {
- try {
- //处理非Web环境报错
- tokens = StpUtil.getTokenValue();
- } catch (Exception e) {
- }
- }
- if (tokens != null) {
- if (StpUtil.getLoginIdByToken(tokens) != null) {
- userInfo = (UserInfo) StpUtil.getTokenSessionByToken(tokens).get(USER_INFO_KEY);
- }
- }
- if (userInfo == null) {
- userInfo = new UserInfo();
- }
- return userInfo;
- }
- /**
- * 获取用户缓存
- *
- * @return
- */
- public static UserInfo getUser() {
- // if(StpUtil.getTokenValue() == null){
- // return new UserInfo();
- // }
- UserInfo userInfo = USER_CACHE.get();
- if (userInfo != null) {
- return userInfo;
- }
- userInfo = UserProvider.getUser(null);
- if (userInfo.getUserId() != null) {
- USER_CACHE.set(userInfo);
- }
- return userInfo;
- }
- // =================== Token相关操作 ===================
- /**
- * 去除Token前缀
- *
- * @param token
- * @return
- */
- public static String cutToken(String token) {
- if (token != null && token.startsWith(TOKEN_PREFIX_SP)) {
- token = token.substring(TOKEN_PREFIX_SP.length());
- }
- return token;
- }
- /**
- * 获取token
- */
- public static String getToken() {
- String toke = getAuthorize();
- return toke;
- }
- /**
- * 获取Authorize
- */
- public static String getAuthorize() {
- String authorize = ServletUtil.getHeader(Constants.AUTHORIZATION);
- return authorize;
- }
- /**
- * TOKEN续期
- */
- public static void renewTimeout(String token) {
- if (StpUtil.getTokenValue() != null) {
- UserInfo userInfo = UserProvider.getUser(token);
- if(userInfo.getUserId() == null || userInfo.getTokenTimeout() == null) {
- //避免请求过网关之后TOKEN失效(携带TOKEN调用登录接口之后账号被顶替)
- return;
- }
- StpUtil.renewTimeout(userInfo.getTokenTimeout() * 60L);
- if(userInfo.getIsAdministrator()) {
- SaSession saSession = StpUtil.getSessionByLoginId(splicingLoginId(Constants.ADMIN_KEY), false);
- if (saSession != null) {
- saSession.updateTimeout(userInfo.getTokenTimeout() * 60L);
- }
- }
- }
- }
- /**
- * 获取所有Token记录
- * 包含无效状态的用户、临时用户
- *
- * @return
- */
- public static List<String> getLoginUserListToken() {
- return StpUtil.searchTokenValue("", -1, -1, true).stream().map(token -> token.replace(StpUtil.stpLogic.splicingKeyTokenValue(""), "")).collect(Collectors.toList());
- }
- // =================== 临时Token相关操作 ===================
- /**
- * 获取内部服务传递验证TOKEN
- *
- * @return
- */
- public static String getInnerAuthToken() {
- return SaSameUtil.getToken();
- }
- /**
- * 验证内部传递Token是否有效 抛出异常
- * @param token
- */
- public static void checkInnerToken(String token){
- SaSameUtil.checkToken(token);
- }
- /**
- * 验证内部传递Token是否有效
- * @param token
- */
- public static boolean isValidInnerToken(String token){
- return SaSameUtil.isValid(token);
- }
- // =================== 退出相关操作 ===================
- /**
- * 根据用户ID踢出全部用户
- * @param userId
- */
- public static void kickoutByUserId(String userId, String tenantId) {
- StpUtil.kickout(splicingLoginId(userId, tenantId));
- }
- /**
- * 根据Token踢出指定会话
- * @param tokens
- */
- public static void kickoutByToken(String... tokens) {
- for (String token : tokens) {
- StpUtil.kickoutByTokenValue(token);
- }
- }
- /**
- * 退出当前Token, 不清除用户其他系统缓存
- */
- public static void logout() {
- StpUtil.logout();
- }
- /**
- * 退出指定Token, 不清除用户其他系统缓存
- *
- * @param token
- */
- public static void logoutByToken(String token) {
- if (token == null) {
- logout();
- } else {
- StpUtil.logoutByTokenValue(cutToken(token));
- }
- }
- /**
- * 退出指定设备类型的用户的全部登录信息, 不清除用户其他系统缓存
- *
- * @param userId
- * @param deviceType
- */
- public static void logoutByUserId(String userId, DeviceType deviceType) {
- StpUtil.logout(splicingLoginId(userId), deviceType.getDevice());
- }
- /**
- * 退出指定用户的全部登录信息, 清除相关缓存
- *
- * @param userId
- */
- public static void logoutByUserId(String userId) {
- StpUtil.logout(splicingLoginId(userId));
- removeOtherCache(userId);
- }
- // =================== 用户权限 ===================
- /**
- * 获取当前用户拥有的权限列表(菜单编码列表、功能ID列表)
- * @return
- */
- public static List<String> getPermissionList(){
- return StpUtil.getPermissionList();
- }
- /**
- * 获取当前用户拥有的角色列表
- * @return
- */
- public static List<String> getRoleList(){
- return StpUtil.getRoleList();
- }
- // =================== 其他缓存相关操作 ===================
- /**
- * 移除
- */
- public static void removeOtherCache(String userId) {
- redisUtil.remove(cacheKeyUtil.getUserAuthorize() + userId);
- redisUtil.remove(cacheKeyUtil.getSystemInfo());
- }
- /**
- * 是否在线
- */
- public boolean isOnLine(String userId) {
- return StpUtil.getTokenValueByLoginId(splicingLoginId(userId), getDeviceForAgent().getDevice()) != null;
- }
- /**
- * 是否登陆
- */
- public static boolean isLogined() {
- return StpUtil.isLogin();
- }
- /**
- * 指定Token是否有效
- * @param token
- * @return
- */
- public static boolean isValid(String token) {
- return StpUtil.getLoginIdByToken(token) != null;
- }
- public static DeviceType getDeviceForAgent() {
- if (ServletUtil.getIsMobileDevice()) {
- return DeviceType.APP;
- } else {
- return DeviceType.PC;
- }
- }
- /**
- * 判断用户是否是临时用户
- * @param userInfo
- * @return
- */
- public static boolean isTempUser(UserInfo userInfo){
- if(userInfo == null){
- userInfo = getUser();
- }
- return DeviceType.TEMPUSER.getDevice().equals(userInfo.getLoginDevice())
- || DeviceType.TEMPUSERLIMITED.getDevice().equals(userInfo.getLoginDevice());
- }
- }
|