添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
咆哮的馒头  ·  Get Nth Entry from ...·  2 周前    · 
留胡子的汤圆  ·  SharePoint 搜索 REST ...·  2 周前    · 
没有腹肌的开水瓶  ·  Exception in thread ...·  2 周前    · 
严肃的牙膏  ·  Self-Training综述 | Helic·  4 月前    · 
痴情的冲锋衣  ·  HTML5 ...·  8 月前    · 
欢乐的篮球  ·  mysql ...·  11 月前    · 

spring实现同一账号同一时间只能在同一个地方登录

这里先说一下大致思路:当系统验证用户的账号密码通过后,获取该用户的sessionid(每一个用户创建的sessionid是唯一的),和用户id(用户的唯一标识,用账号也可以),讲Userid作为键,sessionid作为值放入map中,再将map放入application,如果此后有其他人用同一个账号登录,将用户信息放入map后,会将先前的map覆盖掉(因为useid相同),写一个过滤器,用户操作时判断用户的sessionid是否于map中的sessionid相同,如果相同则继续执行,如果不同,意味着该用户被挤掉了,移除该用户的session,具体步骤如下

1、登录验证通过后,将该用户的id和sessionid方式Map中

  //得到该用户的id
  String strLoginUserId = objUserInfo.getUserid();
  //判断该用户是否已经异地登录,如果异地登录,消除先前的session
  Map<String,String> map=application.getAttribute("listUserSession")==null
					?new HashMap<String,String>():(Map<String,String>)application.getAttribute("listUserSession");
  String sesssionid=session.getId();
  map.put(strLoginUserId, sesssionid);
  application.setAttribute("listUserSession", map);
<filter>
    <filter-name>sessionFilter</filter-name>
    <filter-class>com.sps.util.SessionFilter</filter-class>
</filter> 
<filter-mapping>
    <filter-name>sessionFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping> 

判断session

// 执行过滤
// 从session中获取登录者实体
//获取application
HttpSession session=request.getSession();
//获取applicaiton			
ServletContext application=session.getServletContext();
//获取session的值
 LoginSysOrganInfo objLogin = (LoginSysOrganInfo) session.getAttribute("loginuser");
 //获取application的值
 Map<String,String> map=(Map<String,String>)application.getAttribute("listUserSession");
 if (objLogin != null) {
 //判断是否出现异地登录
boolean flag=false;
if(map!=null&&objLogin!=null){
String userid=objLogin.getUserid();
String sessionid=session.getId();
//便利map,推荐,对容量较大的很实用
for(Map.Entry<String, String> tempMap:map.entrySet()){
if(userid.equals(tempMap.getKey()))
//sessionid不等于map里面的出现异地登录
if(!(sessionid.equals(tempMap.getValue()))){
flag=true;
session.removeAttribute("loginuser");
break;
if(flag){
//获取out
PrintWriter out = response.getWriter();							
out.print("<script charset='UTF-8'>");
out.print("  alert('The user login in other place!');");
out.print("  window.top.location.href = '" + loginUrl+ "';");
out.print("</script>");
return;

 3、如果用户退出移除map中该用户的信息

HttpSession session = req.getSession();
 ServletContext application=session.getServletContext();
 //退出时需要移除该map里面该用户的信息
  Map<String,String> map=(Map<String,String>)application.getAttribute("listUserSession");
 LoginSysOrganInfo objLogin = (LoginSysOrganInfo) session.getAttribute("loginuser");
if(map!=null&&objLogin!=null){			   
   String userid=objLogin.getUserid();
   //遍历map,推荐,对容量较大的很实用
for(Map.Entry<String, String> tempMap:map.entrySet()){
if(userid.equals(tempMap.getKey())){
map.remove(tempMap.getKey());
break;

4、可能遇到的问题

情况一:如果用户没点击退出而是直接关闭了浏览器

情况二:存放用户信息的session超时

这两种情况和步骤3不同,系统无法移除applicaiotn中Map已退出用户的信息,如果用户量过大时,太占用服务器内存,解决办法有两个

方法1:设置一个定时器,隔一段时间清楚一次application

缺点:如果清除application时(这里为凌晨3点)出现同一账号同一时间多次登录,系统无法判断之所以设置凌晨3点,是因为此时登录的情况比较少

//每天凌晨3点执行,
@Scheduled(cron = "0 0 3 * * ?")
public void deletelog() throws NormalException {
try {
//清理application,释放服务器压力
WebApplicationContext webApplicationContext=ContextLoader.getCurrentWebApplicationContext();
ServletContext application=webApplicationContext.getServletContext();
Map<String,String> map=(Map<String,String>)application.getAttribute("listUserSession");
application.removeAttribute("listUserSession");
} catch (Exception e) {
throw new NormalException(e.getMessage(), e);
方法二:用户每次登录时用System.currentTimeMillis()得到时间,将userid作为map的键,把sessionid及time放入对象中作为Map的值,设计一定时器,根据需要设计定时器执行的间隔,再次得到系统时间,减去对象中用户登录的时间,大于某个值(用户session存在的时长),移除map中该用户的信息,这里不做过多描述,大家可以尝试尝试 

缺点:合理设计定时器的间隔,如果定时器间隔太短,对服务器压力太大,如果有一个机制让用在距用户登录时(每个用户登录时,定时器只能设定多长时间执行一次,不能动态设定在某个时间之后自动执行)多长时间后执行,那就太好了

    第一次写博客,代码整理的不是太好看,语言描述不太恰当,还望大家谅解 。。。

spring实现同一账号同一时间只能在同一个地方登录这里先说一下大致思路:当系统验证用户的账号密码通过后,获取该用户的sessionid(每一个用户创建的sessionid是唯一的),和用户id(用户的唯一标识,用账号也可以),讲Userid作为键,sessionid作为值放入map中,再将map放入application,如果此后有其他人用同一个账号登录,将用户信息放入map后,会将先前的m 有关于同一时间用户只能在一个地方登录的问题 以下内容可能将的有点罗嗦,思路或者不清晰,请各位高手手下留情,肯定有更好的方法了,各位高手如果有的话,可否分享一下,谢谢! 1.在服务器,用户每次登录session都不一致,但是session内容中的登录信息或许一致,但是这里还存在一个时间差,如何判断同一个用户在别的地方登录呢 可以比对时间,根据时间大小来判断,当然时间大的就需要留下来了,...
相信很多人在移动开发中都会遇到这样的需求,当手机端的一个账号已经登录的情况下,限制这个账号在另一个设备上同时登录账号自动登录。其实要做到这个的方法有很多,在这里我说下目前使用最多的一种方法: 在开发的时候,和后台协商定义一个token字段,在每次通过输入账号密码登录的情况下,后台生成一个token(一般为字符串)保存在数据库或其他方式,并返回给客户端,客户端接收后保存在本地(可以是数据库,也可
spring-session解决同一账户,单个设备登录 项目是BS架构,在使用spring-session掌管的了session以后,很灵活的解决了分布的session处理,但是万恶的运营提出了万恶的需求,让同一账户只能在单个设备上登录,如果新的设备登录了相同账号,原来的的账户登录状态要自动失效。 好吧,既然提了需求只能,搞起来,项目是spring-session与redis处理的登录...
如若个人理解有误,文章中有不正确的地方,希望大家批评指正,我会继续学习,及时改正。 本文主旨实现用户登陆并且限制同一个用户只在一个地方是登陆状态,并没有用Zuul实现,是自己的一个实现方法。 项目架构:Spring Boot + Spring Cloud + Angularjs(前端),前端会控制未登录时只...
登录 token redis key的生成 并限制用户只能登录1个 当登录两个浏览同时访问时会挤掉另外一个 或者可以登录多个账号 这个自己根据自己的需求设计 生成token使用 redis 进行生成 格式为 token+用户id(此id为md5加密 因为不想让用户直接看到自己的id )+生成的token秘钥 实例 “tokenakwdoadwmamd.awdawdawernfiwonefowenfew.ewrfeorjnqwneqweqwe”:“用户基本信息” 当用户登录成功时 拿用户id 进行加密 并且
spring security关于session management的实现     请参考:http://group.jobbole.com/24133/ 根据上面博文添加相应代码后,并不能实现使上一次登陆失效。要实现请参考下面的博文:     http://blog.csdn.net/xusanhong/article/details/53260373 到此就可以实现Sprin
@SpringBootApplication public class application{ public static void main (String[] args) { SpringApplication.run(Application.class); public static ManagerSessions manage...
可以考虑在数据库中创建一个用户表,包含用户的信息和角色信息。用户登录时,根据用户名和密码查询用户表,获取用户的角色信息,然后根据不同的角色跳转到不同的页面。 在Spring Boot中,可以使用Spring Security来实现角色授权和认证功能。具体步骤如下: 1. 添加Spring Security依赖 在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> 2. 配置Spring Security 在Spring Boot应用程序中,可以通过创建一个继承了WebSecurityConfigurerAdapter的配置类来配置Spring Security。 ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private CustomUserDetailsService userDetailsService; @Override protected void configure(HttpSecurity http) throws Exception { .authorizeRequests() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/user/**").hasRole("USER") .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .defaultSuccessUrl("/") .permitAll() .and() .logout() .permitAll(); @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService); @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); 在上面的配置中,我们定义了两个角色:ADMIN和USER,分别对应管理员和普通用户。我们还定义了一个CustomUserDetailsService类,用于从数据库中获取用户信息。 3. 创建自定义UserDetailsService 可以通过继承UserDetailsService接口来创建自定义的UserDetailsService类,用于从数据库中获取用户信息。 ```java @Service public class CustomUserDetailsService implements UserDetailsService { @Autowired private UserRepository userRepository; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User user = userRepository.findByUsername(username); if (user == null) { throw new UsernameNotFoundException("User not found"); return new CustomUserDetails(user); 在上面的代码中,我们通过userRepository从数据库中获取了用户信息,并将其封装到了一个CustomUserDetails对象中返回。 4. 创建自定义UserDetails 可以通过继承UserDetails接口来创建自定义的UserDetails类,用于封装从数据库中获取的用户信息。 ```java public class CustomUserDetails implements UserDetails { private User user; public CustomUserDetails(User user) { this.user = user; @Override public Collection<? extends GrantedAuthority> getAuthorities() { List<GrantedAuthority> authorities = new ArrayList<>(); for (Role role : user.getRoles()) { authorities.add(new SimpleGrantedAuthority(role.getName())); return authorities; @Override public String getPassword() { return user.getPassword(); @Override public String getUsername() { return user.getUsername(); @Override public boolean isAccountNonExpired() { return true; @Override public boolean isAccountNonLocked() { return true; @Override public boolean isCredentialsNonExpired() { return true; @Override public boolean isEnabled() { return true; 在上面的代码中,我们从User对象中获取了角色信息,并将其封装到了一个List<GrantedAuthority>对象中返回。 5. 创建Controller 最后,创建Controller来处理用户登录和访问控制。 ```java @Controller public class HomeController { @GetMapping("/") public String home() { return "home"; @GetMapping("/admin") public String admin() { return "admin"; @GetMapping("/user") public String user() { return "user"; @GetMapping("/login") public String login() { return "login"; 在上面的代码中,我们定义了四个访问路径:/,/admin,/user和/login。/路径对应home页面,/admin路径对应管理员页面,/user路径对应普通用户页面,/login路径对应登录页面。 以上就是基于Spring Boot实现学生宿舍管理系统同一表分三个角色登录功能的步骤。