欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-05-03 23:38:15
用户唯一登陆需求:要求当账号第一次被登陆时可以正常登陆,当账号在别处登陆时,将退出之前登陆。大概流程如下:项目启动时,首先清空之前登陆记录,防止出错。第一次登陆判断redis是否有登陆记录,没有则登陆成功。第二次登陆判断redis有登陆记录,获取之前登陆记录并删除,第二次登陆成功。一、将redis缓存删除。创建启动类并实现CommandLineRunner接口。首先说明我将登陆用户名作为key,sessionID作为value存入redis。记得在启动类加@ServletComponentScan...

用户唯一登陆需求:要求当账号第一次被登陆时可以正常登陆,当账号在别处登陆时,将退出之前登陆。
大概流程如下:
springboot基于redis实现用户唯一登陆
项目启动时,首先清空之前登陆记录,防止出错。第一次登陆判断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

相关标签: springboot java