老项目ssh 要限制用户做唯一登录,比如在谷歌浏览器登录之后,然后再用IE登录,那么谷歌 上的用户就会失效,项目用的session。所以记录一下如何管理,接下来演示代码以springboot的使用测试,原理一样。主要以session监听器做处理操作。
项目的权限校验使用拦截器做处理
@Component
public class LoginIntecptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
User user = (User)request.getSession().getAttribute("user");
if(user==null){
response.sendRedirect("/toLogin");
return false;
}
return true;
}
}
让拦截器生效
@Configuration
public class MvcConfig implements WebMvcConfigurer {
@Autowired
LoginIntecptor loginIntecptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginIntecptor).addPathPatterns("/**").excludePathPatterns("/login","/toLogin");
}
}
定义session容器
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class MySessionContext {
private static MySessionContext instance;
private Map<String,HttpSession> sessionMap;
private MySessionContext() {
sessionMap = new ConcurrentHashMap<String,HttpSession>();
}
public static MySessionContext getInstance() {
if (instance == null) {
instance = new MySessionContext();
}
return instance;
}
public synchronized void addSession(HttpSession session) {
if (session != null) {
sessionMap.put(session.getId(), session);
}
}
public synchronized void delSession(HttpSession session) {
//session过期或者手动设置无效的时候手动移除key
UserContext.removeKeyByValue(session.getId());
if (session != null) {
sessionMap.remove(session.getId());
}
}
public synchronized HttpSession getSession(String sessionID) {
if (sessionID == null) {
return null;
}
return sessionMap.get(sessionID);
}
}
session监听器
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
@Component
public class SessionListener implements HttpSessionListener {
private MySessionContext myc = MySessionContext.getInstance();
/**
* 添加session
* @param e
*/
@Override
public void sessionCreated(HttpSessionEvent e) {
System.out.println("监听到 session 创建, sessionid 是: " + e.getSession().getId());
myc.addSession(e.getSession());
}
/**
* 移除session
* @param e
*/
@Override
public void sessionDestroyed(HttpSessionEvent e) {
System.out.println("监听到 session 销毁, sessionid 是: " + e.getSession().getId());
myc.delSession(e.getSession());
}
}
用户和session对应关系容器
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class UserContext {
private static Map<Integer,String> userMap = new ConcurrentHashMap<>();
/**
* 存入
* @param userId
* @param sessionId
*/
public static void put(Integer userId,String sessionId){
userMap.put(userId,sessionId);
}
/**
* 获取
* @param userId
* @return
*/
public static String get(Integer userId){
return userMap.get(userId);
}
/**
* 移除key
* @param userId
*/
public static void remove(Integer userId){
userMap.remove(userId);
}
/**
* 根据value移除key
* @param value
*/
public static void removeKeyByValue(String value){
Set<Integer> keys = userMap.keySet();
for(Integer userId: keys){
String s = userMap.get(userId);
if(s.equals(value)){
userMap.remove(userId);
}
}
}
}
测试代码
@GetMapping("/toLogin")
public ModelAndView loginPage(){
return new ModelAndView("login");
}
@GetMapping("/success")
public ModelAndView success(){
return new ModelAndView("success");
}
@GetMapping("/login")
public void login(User user, HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
if(user==null){
response.sendRedirect("toLogin");
}
String sessionId = UserContext.get(user.getId());
if(!StringUtils.isEmpty(sessionId)){//说明用户已经登录了
HttpSession session1 = MySessionContext.getInstance().getSession(sessionId);//移除原来的
session1.invalidate();
}
UserContext.put(user.getId(),session.getId());//重新覆盖
request.getSession().setAttribute("user",user);
response.sendRedirect("success");
}
@GetMapping("/logout")
public void logout(HttpServletRequest request, HttpServletResponse response) throws IOException {
request.getSession().invalidate();
//return new ModelAndView("login");
response.sendRedirect("toLogin");
}
效果就不给你们提供了,随便看看就行了,代码也比较简单,了解即可。
|