精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Java 中實現(xiàn)用戶登錄次數(shù)限制的多種方案

開發(fā) 前端
如果你是單機應用,ConcurrentHashMap? 和 ScheduledExecutorService? 可能是個不錯的選擇;如果是分布式系統(tǒng),使用 Redis? 方案會更有優(yōu)勢;而對于 Spring? 框架的項目,Spring Security 方案會更貼合你的需求。?

前言

在開發(fā)應用程序時,為了保障系統(tǒng)的安全性,我們常常需要對用戶的登錄行為進行限制,比如規(guī)定用戶在 5 分鐘內(nèi)最多允許嘗試登錄 3 次,如果超過次數(shù),就鎖定當前用戶。今天我們就來探討幾種在 Java 中實現(xiàn)這一功能的方案,讓我們的系統(tǒng)更加安全可靠。

使用 HashMap 和 Timer 實現(xiàn)

首先,我們創(chuàng)建一個 HashMap 來存儲用戶登錄失敗的信息。這個 HashMap 中的鍵是用戶名,而值是一個自定義的 LoginAttempt 對象,它包含登錄失敗次數(shù)和最近一次失敗時間。當用戶進行登錄操作時,我們會檢查 HashMap 中是否存在該用戶的記錄。若存在,會查看是否超過 5 分鐘,如果超過,我們將重置失敗次數(shù);如果未超過且次數(shù)已達 3 次,將拒絕登錄。同時,我們使用 Timer 來清理過期的記錄。

示例

public class LoginAttempt {
    int attempts;
    long lastAttemptTime;

    public LoginAttempt() {
        this.attempts = 0;
        this.lastAttemptTime = System.currentTimeMillis();
    }
}

public class LoginService {
    private static final Map<String, LoginAttempt> loginAttempts = new HashMap<>();
    private static final long LOCKOUT_DURATION = 5 * 60 * 1000; // 5 minutes in milliseconds
    private static final int MAX_ATTEMPTS = 3;

    public static boolean isLoginAllowed(String username) {
        LoginAttempt attempt = loginAttempts.get(username);
        if (attempt == null) {
            return true;
        }
        long currentTime = System.currentTimeMillis();
        if (currentTime - attempt.lastAttemptTime > LOCKOUT_DURATION) {
            loginAttempts.remove(username);
            return true;
        }
        if (attempt.attempts >= MAX_ATTEMPTS) {
            return false;
        }
        return true;
    }

    public static void recordFailedLogin(String username) {
        LoginAttempt attempt = loginAttempts.get(username);
        if (attempt == null) {
            attempt = new LoginAttempt();
            loginAttempts.put(username, attempt);
        }
        attempt.attempts++;
        attempt.lastAttemptTime = System.currentTimeMillis();
    }

    public static void main(String[] args) {
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                long currentTime = System.currentTimeMillis();
                loginAttempts.entrySet().removeIf(entry -> currentTime - entry.getValue().lastAttemptTime > LOCKOUT_DURATION);
            }
        }, LOCKOUT_DURATION, LOCKOUT_DURATION);

        // 模擬登錄嘗試
        String username = "testUser";
        for (int i = 0; i < 5; i++) {
            if (isLoginAllowed(username)) {
                System.out.println("Login allowed");
                // 模擬登錄成功,重置嘗試次數(shù)
                loginAttempts.remove(username);
            } else {
                System.out.println("Login not allowed, user locked");
            }
            recordFailedLogin(username);
        }
    }
}

使用 ConcurrentHashMap 和 ScheduledExecutorService 實現(xiàn)

這里我們使用 ConcurrentHashMap 來存儲用戶登錄失敗信息,它支持并發(fā)訪問。并且使用 ScheduledExecutorService 來進行定時清理過期記錄,避免 Timer 的一些潛在問題,如可能導致的內(nèi)存泄漏,更適合高并發(fā)場景。

示例

public class LoginAttempt {
    int attempts;
    long lastAttemptTime;

    public LoginAttempt() {
        this.attempts = 0;
        this.lastAttemptTime = System.currentTimeMillis();
    }
}

public class LoginService {
    private static final ConcurrentHashMap<String, LoginAttempt> loginAttempts = new ConcurrentHashMap<>();
    private static final long LOCKOUT_DURATION = 5 * 60 * 1000; // 5 minutes in milliseconds
    private static final int MAX_ATTEMPTS = 3;
    private static final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();

    static {
        executorService.scheduleAtFixedRate(() -> {
            long currentTime = System.currentTimeMillis();
            loginAttempts.entrySet().removeIf(entry -> currentTime - entry.getValue().lastAttemptTime > LOCKOUT_DURATION);
        }, LOCKOUT_DURATION, LOCKOUT_DURATION, TimeUnit.MILLISECONDS);
    }

    public static boolean isLoginAllowed(String username) {
        LoginAttempt attempt = loginAttempts.get(username);
        if (attempt == null) {
            return true;
        }
        long currentTime = System.currentTimeMillis();
        if (currentTime - attempt.lastAttemptTime > LOCKOUT_DURATION) {
            loginAttempts.remove(username);
            return true;
        }
        if (attempt.attempts >= MAX_ATTEMPTS) {
            return false;
        }
        return true;
    }

    public static void recordFailedLogin(String username) {
        loginAttempts.compute(username, (key, value) -> {
            if (value == null) {
                return new LoginAttempt();
            }
            value.attempts++;
            value.lastAttemptTime = System.currentTimeMillis();
            return value;
        });
    }

    public static void main(String[] args) {
        // 模擬登錄嘗試
        String username = "testUser";
        for (int i = 0; i < 5; i++) {
            if (isLoginAllowed(username)) {
                System.out.println("Login allowed");
                // 模擬登錄成功,重置嘗試次數(shù)
                loginAttempts.remove(username);
            } else {
                System.out.println("Login not allowed, user locked");
            }
            recordFailedLogin(username);
        }
    }
}

使用 Redis 存儲登錄嘗試信息

借助 Redis 的鍵值存儲,我們將用戶的登錄失敗次數(shù)和最近一次失敗時間存儲起來,并利用 Redis 的 TTL(Time To Live)功能自動清理過期記錄。在用戶登錄時,從 Redis 獲取信息,據(jù)此判斷是否允許登錄。

示例

public class LoginService {
    private static final Jedis jedis = new Jedis("localhost", 6379);
    private static final long LOCKOUT_DURATION = 5 * 60; // 5 minutes in seconds
    private static final int MAX_ATTEMPTS = 3;

    public static boolean isLoginAllowed(String username) {
        String attemptsKey = "login_attempts:" + username;
        String attemptsStr = jedis.get(attemptsKey);
        if (attemptsStr == null) {
            return true;
        }
        String[] parts = attemptsStr.split(":");
        int attempts = Integer.parseInt(parts[0]);
        long lastAttemptTime = Long.parseLong(parts[1]);
        long currentTime = System.currentTimeMillis() / 1000;
        if (currentTime - lastAttemptTime > LOCKOUT_DURATION) {
            jedis.del(attemptsKey);
            return true;
        }
        if (attempts >= MAX_ATTEMPTS) {
            return false;
        }
        return true;
    }

    public static void recordFailedLogin(String username) {
        String attemptsKey = "login_attempts:" + username;
        String attemptsStr = jedis.get(attemptsKey);
        long currentTime = System.currentTimeMillis() / 1000;
        if (attemptsStr == null) {
            jedis.setex(attemptsKey, (int) LOCKOUT_DURATION, "1:" + currentTime);
        } else {
            String[] parts = attemptsStr.split(":");
            int attempts = Integer.parseInt(parts[0]);
            jedis.setex(attemptsKey, (int) LOCKOUT_DURATION, (attempts + 1) + ":" + currentTime);
        }
    }

    public static void main(String[] args) {
        // 模擬登錄嘗試
        String username = "testUser";
        for (int i = 0; i < 5; i++) {
            if (isLoginAllowed(username)) {
                System.out.println("Login allowed");
                // 模擬登錄成功,刪除嘗試記錄
                jedis.del("login_attempts:" + username);
            } else {
                System.out.println("Login not allowed, user locked");
            }
            recordFailedLogin(username);
        }
    }
}

補充-滑動窗口

構(gòu)造一個滑動窗口,窗口大小限制5分鐘,然后限流次數(shù)設(shè)置為3次即可實現(xiàn)這個功能了。而滑動窗口我們可以借助Redis來實現(xiàn)。

public class SlidingWindowRateLimiter {
    private Jedis jedis;
    private String key;
    private int limit = 3; //限制請求次數(shù)最大3次
    private int lockTime;  // 鎖定用戶的時間,單位:秒

    public SlidingWindowRateLimiter(Jedis jedis, String key, int limit, int lockTime) {
        this.jedis = jedis;
        this.key = key;
        this.limit = limit;
        this.lockTime = lockTime;  // 鎖定時間    
    }

    public boolean allowRequest() {
        // 當前時間戳,單位:毫秒        
        long currentTime = System.currentTimeMillis();
        // 鎖定鍵的名稱(鎖定的用戶)
        String lockKey = "lock:" + key;
        // 檢查用戶是否已被鎖定
        if (jedis.exists(lockKey)) {
            returnfalse;  // 用戶已被鎖定,返回 false        
        }
        // 使用Lua腳本來確保原子性操作
        String luaScript = "local window_start = ARGV[1] - 300000\n" + // 計算5分鐘的起始時間
                "redis.call('ZREMRANGEBYSCORE', KEYS[1], '-inf', window_start)\n" +  // 清理過期的請求
                "local current_requests = redis.call('ZCARD', KEYS[1])\n" +  // 獲取當前請求次數(shù)
                "if current_requests < tonumber(ARGV[2]) then\n" +  // 如果請求次數(shù)小于限制
                "    redis.call('ZADD', KEYS[1], ARGV[1], ARGV[1])\n" +  // 添加當前請求時間
                "    return 1\n" +  // 允許請求
                "else\n" +
                "    redis.call('SET', 'lock:'..KEYS[1], 1, 'EX', tonumber(ARGV[3]))\n" +  // 鎖定用戶
                "    return 0\n" +  // 拒絕請求
                "end";
        // 調(diào)用 Lua 腳本進行原子操作
        Object result = jedis.eval(luaScript, 1, key, String.valueOf(currentTime), String.valueOf(limit), String.valueOf(lockTime));
        // 返回操作結(jié)果
        return (Long) result == 1;
    }
}

使用 Spring Security 實現(xiàn)

我們還可以使用 Spring Security 的相關(guān)組件來實現(xiàn)。利用 AuthenticationFailureHandler 記錄登錄失敗信息,在 UserDetailsService 的 loadUserByUsername 方法中檢查用戶是否被鎖定,使用 UserDetails 的 isAccountNonLocked 屬性表示用戶是否被鎖定。

示例

public class CustomAuthenticationProvider implements AuthenticationProvider {
    private UserDetailsService userDetailsService;
    private PasswordEncoder passwordEncoder;
    private Map<String, LoginAttempt> loginAttempts = new HashMap<>();
    private static final long LOCKOUT_DURATION = 5 * 60 * 1000; // 5 minutes in milliseconds
    private static final int MAX_ATTEMPTS = 3;

    public CustomAuthenticationProvider(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
        this.passwordEncoder = new BCryptPasswordEncoder();
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String username = authentication.getName();
        String password = authentication.getCredentials().toString();
        UserDetails userDetails;
        try {
            userDetails = userDetailsService.loadUserByUsername(username);
        } catch (UsernameNotFoundException e) {
            throw new BadCredentialsException("Invalid username or password");
        }
        if (!passwordEncoder.matches(password, userDetails.getPassword())) {
            recordFailedLogin(username);
            throw new BadCredentialsException("Invalid username or password");
        }
        if (!isLoginAllowed(username)) {
            throw new BadCredentialsException("User is locked");
        }
        return new UsernamePasswordAuthenticationToken(userDetails, password, userDetails.getAuthorities());
    }

    private boolean isLoginAllowed(String username) {
        LoginAttempt attempt = loginAttempts.get(username);
        if (attempt == null) {
            return true;
        }
        long currentTime = System.currentTimeMillis();
        if (currentTime - attempt.lastAttemptTime > LOCKOUT_DURATION) {
            loginAttempts.remove(username);
            return true;
        }
        if (attempt.attempts >= MAX_ATTEMPTS) {
            return false;
        }
        return true;
    }

    private void recordFailedLogin(String username) {
        LoginAttempt attempt = loginAttempts.get(username);
        if (attempt == null) {
            attempt = new LoginAttempt();
            loginAttempts.put(username, attempt);
        }
        attempt.attempts++;
        attempt.lastAttemptTime = System.currentTimeMillis();
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }

    public static class LoginAttempt {
        int attempts;
        long lastAttemptTime;

        public LoginAttempt() {
            this.attempts = 0;
            this.lastAttemptTime = System.currentTimeMillis();
        }
    }
}

最后

如果你是單機應用,ConcurrentHashMap 和 ScheduledExecutorService 可能是個不錯的選擇;如果是分布式系統(tǒng),使用 Redis 方案會更有優(yōu)勢;而對于 Spring 框架的項目,Spring Security 方案會更貼合你的需求。

責任編輯:武曉燕 來源: 一安未來
相關(guān)推薦

2025-06-05 05:22:00

2018-04-02 10:16:00

bug代碼安卓

2009-12-23 10:46:38

WPF實現(xiàn)用戶界面

2009-12-30 09:45:52

Silverlight

2010-01-28 10:00:54

linux用戶注銷logout

2012-05-04 09:28:49

Linux

2010-08-04 10:48:17

路由器

2021-08-05 10:40:37

加密方案Spring

2024-09-22 10:46:33

數(shù)據(jù)飛輪算法

2016-10-24 23:18:55

數(shù)據(jù)分析漏斗留存率

2024-04-08 14:10:06

2009-09-07 09:20:34

2011-03-24 08:56:23

escalationsNagios報警

2016-05-17 10:03:39

用戶體驗運維可度量

2019-08-22 15:42:03

2025-03-28 04:10:00

2018-05-30 10:22:47

電商平臺

2024-01-10 08:26:16

用戶注冊用戶重復數(shù)據(jù)

2010-06-18 13:52:24

SQL Server查
點贊
收藏

51CTO技術(shù)棧公眾號

久久久久无码精品国产| 污污的网站18| 欧美日本网站| 美国毛片一区二区三区| 欧美日韩成人网| 欧美做受喷浆在线观看| 巨大黑人极品videos精品| 一区二区三区在线观看视频| 免费亚洲精品视频| 国产精品一级二级| 亚洲综合电影一区二区三区| 日韩视频―中文字幕| 国产69视频在线观看| 成人全视频在线观看在线播放高清| 老司机精品视频导航| 久久久欧美精品| 在线观看天堂av| 欧洲亚洲视频| 91精品国产综合久久精品图片 | 少妇性l交大片| 黄视频网站在线| 久久品道一品道久久精品| 成人观看高清在线观看免费| 国产精品999在线观看| 91精品推荐| 精品一区二区三区电影| 女教师高潮黄又色视频| 亚洲欧美在线成人| 欧美日韩视频免费播放| www.国产二区| 麻豆影视在线观看_| 久久先锋资源网| 国产视频一区二区不卡| 国产强伦人妻毛片| 久久成人免费网站| 国产精品扒开腿做爽爽爽男男| 一级黄色性视频| 青青草久久爱| 亚洲第一天堂av| 69亚洲乱人伦| 国产乱人伦精品一区| 欧美一级日韩一级| 国内外成人免费在线视频| 日韩精品一区二区三区| 欧美日韩一区二区在线 | 欧美性猛xxx| 又大又硬又爽免费视频| 免费高清完整在线观看| 国产精品毛片久久久久久| 欧洲亚洲一区二区| 伦理片一区二区三区| 91女神在线视频| 欧美日韩系列| 国产福利片在线| 中文久久乱码一区二区| 日韩不卡av| 成年在线电影| 国产精品伦理在线| 2021狠狠干| av软件在线观看| 亚洲欧美区自拍先锋| 日韩精品手机在线观看| 精品日韩av| 无吗不卡中文字幕| 苍井空浴缸大战猛男120分钟| 老司机午夜在线| 亚洲视频一二三| 青青青在线观看视频| 岛国av在线播放| 日韩欧美精品网址| 中文字幕视频在线免费观看| 亚洲国产一区二区久久| 欧美一区二区三区的| 又黄又爽又色的视频| 亚洲精品一二三**| 日韩国产在线看| 黄色三级生活片| 久久久五月天| 91精品国产91| 国产乱码77777777| 国产老女人精品毛片久久| 国产精品高清一区二区三区| 日本私人网站在线观看| 国产精品美女久久久久aⅴ| 久久天天东北熟女毛茸茸| 国产精品—色呦呦| 91福利小视频| 丰满饥渴老女人hd| 校花撩起jk露出白色内裤国产精品| 日韩欧美一区二区久久婷婷| 欧产日产国产精品98| 亚洲欧洲av| 久久精品成人欧美大片古装| 日韩毛片在线播放| 男人的天堂亚洲一区| 97视频资源在线观看| 蜜桃成人在线视频| 一区二区欧美国产| 日本在线观看免费视频| 国产主播性色av福利精品一区| 日韩一级片网址| 少妇大叫太粗太大爽一区二区| 一区中文字幕| 夜夜躁日日躁狠狠久久88av| 久久久无码精品亚洲国产| 亚洲一区欧美激情| 亚洲一区二区中文| 国产精品久久一区二区三区不卡| 久久老女人爱爱| gogogo免费高清日本写真| 免费成人在线电影| 欧美一级日韩不卡播放免费| 欧美狂猛xxxxx乱大交3| 亚洲午夜在线| 成人免费观看a| 精品久久av| 亚洲成在人线免费| 黄页网站在线看| 久久精品播放| 国产精品草莓在线免费观看| 天堂在线视频网站| 一区二区三区成人| 天堂av.com| 日韩理论电影院| 国产不卡视频在线| 日本美女一级视频| 亚洲午夜精品久久久久久久久| 国产男女免费视频| 国产精品色婷婷在线观看| 国产一区二区av| 久久午夜免费视频| 粉嫩aⅴ一区二区三区四区 | 亚洲欧美自偷自拍| 亚洲精品日日夜夜| 亚洲一区二区福利视频| 日韩精品免费| 国产精品美女免费看| 四虎永久在线精品免费网址| 夜夜嗨av一区二区三区网页| 91蝌蚪视频在线| 亚洲欧美偷拍自拍| 91九色蝌蚪成人| 亚洲精品一线| 日韩三区在线观看| 久久国产在线观看| 风流少妇一区二区| 亚洲人成无码网站久久99热国产| 浪潮色综合久久天堂| 亚洲韩国欧洲国产日产av| 久久久久成人精品无码| 成人午夜在线视频| 欧美不卡在线播放| 欧美久久精品| 日韩av成人在线| 国内在线精品| 欧美日韩一区二区在线观看视频 | 久久综合九色综合欧美就去吻| 日韩电影天堂视频一区二区| 欧美xxx网站| 国产一区二区三区四区福利| 99久久久无码国产精品免费蜜柚| 国产乱码精品一区二区三| 国产欧美综合一区| 1204国产成人精品视频| 久久久欧美一区二区| 天天摸天天碰天天爽天天弄| 91国模大尺度私拍在线视频 | 久久美女高清视频 | 亚洲国产影院| 久久精品午夜一区二区福利| 精品91久久| 色偷偷9999www| 国产肥老妇视频| 婷婷中文字幕综合| 亚洲一区二区三区蜜桃| 激情综合网天天干| 日本熟妇人妻xxxx| 国产精品片aa在线观看| 成人免费在线视频网站| 丁香花在线电影| 国产亚洲欧美日韩美女| 97国产成人无码精品久久久| 亚洲在线视频网站| 97超碰在线资源| 国产精品18久久久久久vr| 看av免费毛片手机播放| 99久久99久久精品国产片桃花| 国产精品福利小视频| 欧美午夜电影一区二区三区| 日韩欧美自拍偷拍| 精品成人无码久久久久久| 亚洲男人电影天堂| 国产黄片一区二区三区| 黄一区二区三区| 青青青在线播放| 一区二区三区四区在线观看国产日韩 | 日本女人性生活视频| 国产成人av影院| 男人插女人下面免费视频| 欧美日韩爆操| 一区二区三区偷拍| 亚洲人成网77777色在线播放| 国内精品一区二区三区| 国产福利小视频在线| 精品成人a区在线观看| 亚洲免费视频二区| 精品久久久久久久久中文字幕| 超碰97在线资源站| 久久99精品国产.久久久久久 | 影音先锋久久| 一级二级三级欧美| 亚洲免费成人av在线| 国产精品国产一区二区| 日韩在线电影| 国产精品高清在线观看| 蜜桃麻豆影像在线观看| 久久97精品久久久久久久不卡| 亚洲美女综合网| 欧美日韩成人一区| 精人妻无码一区二区三区| 亚洲午夜影视影院在线观看| 欧美性生给视频| 中文字幕免费不卡| 国产成人av一区二区三区不卡| 日韩精品免费专区| 免费不卡av在线| 欧美日韩精品一本二本三本| 一卡二卡3卡四卡高清精品视频| 国产一区二区av在线| 国产精品视频不卡| 日本欧美韩国| 国产成人自拍视频在线观看| 涩涩视频网站在线观看| 97精品免费视频| 国产不卡123| 7777免费精品视频| 国产黄色大片在线观看| 欧美黑人又粗大| 91在线中文| 欧美极品少妇与黑人| 欧美wwww| 欧美精品久久久久a| 国产三级伦理在线| 96精品视频在线| 91白丝在线| 91地址最新发布| 伊人色综合一区二区三区影院视频| 日韩中文在线中文网三级| 成人免费一区二区三区视频网站| 911精品产国品一二三产区| 亚洲一级在线播放| 欧美精品免费视频| aa视频在线免费观看| 日韩一级欧美一级| 亚洲精品一区二区三区新线路| 欧美丝袜一区二区三区| 久草手机在线视频| 在线观看一区二区视频| 日本一区二区三区久久| 欧美色视频在线| 国产三区在线播放| 精品国产免费视频| 日本韩国精品一区二区| 国产亚洲精品高潮| 免费人成在线观看播放视频| 美日韩在线视频| 182在线视频观看| 日韩免费观看在线观看| 欧美激情福利| 91久久在线视频| 欧美三级电影在线| 日韩精品福利视频| 中文字幕一区二区av| 午夜免费福利小电影| 蜜桃久久精品一区二区| 台湾佬美性中文| 久久久久久日产精品| 熟女av一区二区| 欧美日韩国产综合新一区 | 中文字幕在线观看免费高清| 国产精品私人影院| 一区二区三区四区五区| 亚洲一区二区三区在线看| 欧美一区二区三区网站| 欧美精品在线观看一区二区| 色噜噜一区二区三区| 一区二区亚洲欧洲国产日韩| 污污视频在线看| 奇米成人av国产一区二区三区| 黄色羞羞视频在线观看| 国产91在线播放精品91| 欧美午夜在线播放| 欧美日韩一区二区三区在线观看免 | 欧美色精品天天在线观看视频| 国产精品suv一区二区三区| 欧美性生交片4| 黄色美女一级片| 色婷婷综合成人| 松下纱荣子在线观看| 国产日韩欧美夫妻视频在线观看| 99久久伊人| 国产精选在线观看91| 97精品国产| 欧美激情国产精品日韩| 国产盗摄视频一区二区三区| 国产全是老熟女太爽了| 亚洲影院久久精品| 91九色蝌蚪91por成人| 日韩精品视频免费| 色屁屁www国产馆在线观看| 国产精品对白刺激| 欧美激情极品| 欧美日韩福利在线| 国产一区二区不卡在线| 大胸美女被爆操| 欧美视频在线观看 亚洲欧| 亚洲精品一区二区口爆| 日韩中文字幕网| 欧洲成人一区| 免费久久久一本精品久久区| 伊人久久大香线蕉综合热线| 欧洲美女亚洲激情| 中文字幕不卡的av| 国产精品熟女视频| 亚洲激情一二三区| 91av俱乐部| 国产成人亚洲综合a∨猫咪| 网站永久看片免费| 欧美亚洲动漫另类| 成人亚洲综合天堂| 国产精品精品久久久| 亚洲动漫精品| 2022亚洲天堂| 久久天天做天天爱综合色| 日韩男人的天堂| 亚洲国产欧美一区| 美女尤物在线视频| 国产精品免费视频一区二区| 国产精品videosex极品| 日本人妻一区二区三区| 亚洲精品乱码久久久久久久久| 欧美日韩偷拍视频| 91精品国产综合久久久久久久 | 亚洲欧美日韩一区二区三区四区| 欧美日韩免费一区二区三区视频| 国产精品久久久久久免费播放| 日韩欧美一卡二卡| 麻豆传媒在线完整视频| 国产精品午夜视频| 久久免费精品视频在这里| 久久久久久久久久久久久久久国产| 99精品一区二区三区| 日韩成人高清视频| 亚洲激情视频网| 中文字幕在线视频网站| 欧美激情第六页| 久久久精品五月天| 五月天精品视频| 欧美日韩成人一区| 午夜小视频在线观看| 国产一级特黄a大片99| 国产日韩欧美一区二区三区在线观看| 午夜一区二区视频| 一区二区三区日韩欧美| 国产1区在线观看| 51色欧美片视频在线观看| 网友自拍区视频精品| 我要看一级黄色大片| 综合久久久久久久| 东京干手机福利视频| 91精品国产91久久久久久吃药| 婷婷久久免费视频| 国产成人一二三区| 国产+成+人+亚洲欧洲自线| 日韩精品在线不卡| 自拍偷拍亚洲欧美| 亚洲精品一区二区三区在线| 免费观看日韩毛片| 国产精品伦一区| 欧美一级免费片| 国产精品精品久久久| 欧美~级网站不卡| 最近中文字幕免费视频| 欧美精品v国产精品v日韩精品 | 久久久久久久爱| 婷婷精品在线观看| 女同激情久久av久久| 亚洲成av人影院在线观看网| caoporn国产精品免费视频| 91超碰在线电影| 亚洲一区图片| 岛国毛片在线观看| 亚洲片av在线| 视频精品一区二区三区| 久草综合在线观看| 亚洲成人免费观看| 毛片在线不卡| 欧美日韩在线播放一区二区| 国产精品一区二区在线观看网站| 岛国毛片在线观看|