当前位置: 移动技术网 > IT编程>开发语言>Java > springboot基于redis实现用户唯一登陆

springboot基于redis实现用户唯一登陆

2020年08月01日  | 移动技术网IT编程  | 我要评论
用户唯一登陆需求:要求当账号第一次被登陆时可以正常登陆,当账号在别处登陆时,将退出之前登陆。大概流程如下:项目启动时,首先清空之前登陆记录,防止出错。第一次登陆判断redis是否有登陆记录,没有则登陆成功。第二次登陆判断redis有登陆记录,获取之前登陆记录并删除,第二次登陆成功。一、将redis缓存删除。创建启动类并实现CommandLineRunner接口。首先说明我将登陆用户名作为key,sessionID作为value存入redis。记得在启动类加@ServletComponentScan

用户唯一登陆需求:要求当账号第一次被登陆时可以正常登陆,当账号在别处登陆时,将退出之前登陆。
大概流程如下:
在这里插入图片描述
项目启动时,首先清空之前登陆记录,防止出错。第一次登陆判断redis是否有登陆记录,没有则登陆成功。第二次登陆判断redis有登陆记录,获取之前登陆记录并删除,第二次登陆成功。

一、将redis缓存删除。
创建启动类并实现CommandLineRunner接口。首先说明我将登陆用户名作为key,sessionID作为value存入redis。记得在启动类加@ServletComponentScan注解

@Component
public class Runner implements CommandLineRunner {

private final Log logger = LogFactory.getLog(Runner.class);
@Resource
GwUserService gwUserService;
@Resource
private RedisTemplate<String, Object> redisTemplate;

/**
 * 单用户登录设置
 * @param args
 * @throws Exception
 */
@Override
public void run(String... args) throws Exception {
    ***//获取登陆用户名
    for (int i = 0; i < list.size(); i++) {
        if (redisTemplate.opsForValue().get(list.get(i))!=null){
            redisTemplate.opsForValue().set(list.get(i).toString(),null);
        }
    }
    logger.info("redis初始化用户信息完成");
	}
} 

二、接下来是判断是否之前有登陆记录逻辑。

String id = redisTemplate.opsForValue().get(username)+""; //存在跨域问题

        SessionContext myc= SessionContext.getInstance();
        if(id !=null && !"null".equals(id)){//如果获取到之前有人登录过,就将之前用户session注销
            Session sess = myc.getSession(id);
            sess.setAttribute("message","账号已在别处登录");
            sess.setTimeout(3000);
        }
        myc.addSession(currentUser.getSession());
        redisTemplate.opsForValue().set(username, currentUser.getSession().getId()); 

跨域问题下面会有说。这里面通过sessionID获取session,然后设置之前session过期时间。也可以直接调用销毁session方法。

三、通过sessionID获取session

public class SessionContext {
private static SessionContext instance;
private HashMap<String,Session> sessionMap;

private SessionContext() {
    sessionMap = new HashMap<String,Session>();
}

public static SessionContext getInstance() {
    if (instance == null) {
        instance = new SessionContext();
    }
    return instance;
}

public synchronized void addSession(Session session) {
    if (session != null) {
        sessionMap.put(session.getId()+"", session);
    }
}

public synchronized void delSession(Session session) {
    if (session != null) {
        sessionMap.remove(session.getId());
    }
}

public synchronized Session getSession(String sessionID) {
    if (sessionID == null) {
        return null;
    }
    return sessionMap.get(sessionID);
} 

}

三、跨域问题:配置类,当然也需要前端配合。

@Configuration
public class CorsConfig {
// 当前跨域请求最大有效时长。这里默认30天
private long maxAge = 30 * 24 * 60 * 60;

private CorsConfiguration buildConfig() {
    CorsConfiguration corsConfiguration = new CorsConfiguration();
    corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址
    corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
    corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法
    corsConfiguration.setAllowCredentials(true);
    corsConfiguration.setMaxAge(maxAge);
    return corsConfiguration;
}

@Bean
public CorsFilter corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", buildConfig()); // 4 对接口配置跨域设置
    return new CorsFilter(source);
}
} 

到此之后就可以实现唯一登陆了。同一电脑不同浏览器也是可用的哦

本文地址:https://blog.csdn.net/Dcocount/article/details/108236808

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网