精品欧美一区二区三区在线观看 _久久久久国色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ù)棧公眾號

樱花影视一区二区| 蜜臀久久久久久久| 精品丝袜一区二区三区| 亚洲 中文字幕 日韩 无码| 91伦理视频在线观看| 另类成人小视频在线| 欧美片一区二区三区| 亚洲中文字幕无码av| 成人国产一区| 精品久久久久久久久久久久久久| 欧美在线播放一区二区| 国产日韩免费视频| 久久不射网站| 欧美贵妇videos办公室| 国产美女免费网站| 一区二区三区视频免费视频观看网站| 日韩欧美中文免费| 人人妻人人澡人人爽欧美一区 | a'aaa级片在线观看| 久久九九久久九九| 国产精品夜夜夜一区二区三区尤| 在线观看黄色网| 亚洲永久在线| 国内精品免费午夜毛片| 国产日产在线观看| 欧洲杯足球赛直播| 国产丝袜精品视频| 成年人小视频在线观看| 国产日韩一区二区三免费高清| 日韩欧美在线免费| 成人午夜免费在线| 麻豆tv在线| 成人午夜精品一区二区三区| 亚洲亚洲一区二区三区| 亚洲第一黄网| 亚洲国产日韩欧美综合久久 | ,亚洲人成毛片在线播放| 国内精品亚洲| 日韩在线视频二区| 三级男人添奶爽爽爽视频 | 91丨九色丨国产在线| 中文字幕亚洲精品在线| 欧美 日韩 国产 一区| 亚洲精品久久久久中文字幕二区| 欧美视频免费播放| 最新日本在线观看| 欧美国产激情二区三区 | 精品久久人妻av中文字幕| 日韩av电影天堂| 欧美性受xxx| 久久精品第一页| 亚洲91视频| 久久精品国产一区| 中国特黄一级片| 国产精品一区二区三区av麻| 亚洲精品久久久久国产| 国产性生活毛片| 51社区在线成人免费视频| 在线观看免费亚洲| 免费看黄色一级大片| 午夜欧美激情| 五月婷婷久久丁香| 91丨porny丨探花| 成人福利电影| 五月天中文字幕一区二区| 97中文字幕在线| 欧美午夜大胆人体| 亚洲综合在线第一页| 亚洲av综合色区| 制服丝袜在线播放| 一区二区三区在线视频免费| 精品无码av无码免费专区| 主播国产精品| 一区二区三区四区在线播放| 麻豆视频传媒入口| 伊人在我在线看导航| 亚洲码国产岛国毛片在线| 青青草免费在线视频观看| 国产丝袜在线| 一区二区三区美女| 91动漫在线看| 天堂√中文最新版在线| 亚洲va天堂va国产va久| 天堂8在线天堂资源bt| 一个人www视频在线免费观看| 无码av免费一区二区三区试看| 国内自拍在线观看| 深夜成人影院| 91精品国产色综合久久不卡电影| 国产成人av免费观看| 2020最新国产精品| 国产婷婷97碰碰久久人人蜜臀| 中文字幕狠狠干| 日韩电影免费网站| 久久6免费高清热精品| 久久久久久久国产精品毛片| 99综合在线| 国产精品久久久久久一区二区| 在线视频播放大全| 国产99久久久精品| 麻豆传媒一区| 免费在线观看av| 一区二区三区在线免费观看| a√天堂在线观看| 丁香婷婷久久| 日韩三级中文字幕| 国产免费一区二区三区网站免费| 天天色天天射综合网| 久久男人av资源网站| 五月婷婷六月婷婷| 国产在线视频精品一区| 国产日韩欧美综合精品 | 免费成人高清在线视频| 精品人在线二区三区| 全黄一级裸体片| 一区二区三区在线| 日韩av电影免费观看高清| 国产精品久久久久久久成人午夜| 成人短视频下载| 亚洲自拍三区| 英国三级经典在线观看| 欧美一区二区视频网站| 中文字幕狠狠干| 综合激情在线| 国产精品免费一区豆花| 欧美一级片免费| 亚洲欧洲精品一区二区精品久久久 | 国产成人精品777777| 国产在线视频一区二区| 久久久久久久久久码影片| 国产在线69| 欧美日韩国产中文精品字幕自在自线 | 国产黄色免费在线观看| 一区二区在线看| 老熟妇仑乱视频一区二区| 亚洲精品v亚洲精品v日韩精品| 在线视频国产日韩| 真实国产乱子伦对白在线| 日韩国产成人精品| 久久婷婷开心| 伊人手机在线| 337p亚洲精品色噜噜噜| 中文字幕 自拍| 国产亚洲在线观看| 99理论电影网| h片在线观看网站| 欧美性猛交xxxxxxxx| 国产中文字幕一区二区| 一区免费视频| 99视频免费观看| av在线app| 91精品黄色片免费大全| 潘金莲一级黄色片| 奇米一区二区三区av| 欧洲精品在线一区| 深夜成人影院| 精品国产乱码久久久久久蜜臀 | 中文在线免费一区三区| 久久精品在线视频| 91丨九色丨蝌蚪丨对白| 国产精品理论在线观看| 欧美性猛交xxx乱久交| 亚洲春色h网| 欧美一级淫片aaaaaaa视频| 全部免费毛片在线播放一个| 一区二区三区蜜桃| 中国特级黄色大片| 亚洲精品黄色| 欧美精品久久久| 成人黄色免费短视频| 国产偷国产偷亚洲清高网站| 欧美日韩综合一区二区三区| 91色九色蝌蚪| 欧美黄色一级片视频| 精品久久久久久久| 国产精品美女在线| 9191在线观看| 欧美日韩国产高清一区二区| 日韩欧美123区| 国产 日韩 欧美大片| 美女扒开大腿让男人桶| 美女视频亚洲色图| 国产成人精品免高潮费视频| a黄色在线观看| 4438成人网| 久久久久无码国产精品不卡| 成人av在线网| 日日摸天天爽天天爽视频| 日韩精品免费| 亚洲综合国产精品| 青草av在线| 亚洲热线99精品视频| 在线观看毛片av| 亚洲丰满少妇videoshd| 一卡二卡三卡四卡| 狠狠色丁香婷婷综合| 97免费视频观看| 另类图片第一页| 清纯唯美亚洲综合| 黄色动漫在线观看| 欧美精品一区二区蜜臀亚洲| 色屁屁影院www国产高清麻豆| 亚洲国产高清在线观看视频| 中文字幕第66页| 亚洲在线电影| 超碰免费在线公开| 日韩深夜福利| 成人午夜激情网| av岛国在线| 精品国偷自产在线视频99| 日韩在线观看视频一区| 欧美无砖专区一中文字| 国产一级特黄a高潮片| 中文字幕av一区 二区| 亚洲成人激情小说| 欧美a级理论片| 国产尤物av一区二区三区| 日韩欧美高清在线播放| 国产66精品久久久久999小说| 香蕉久久免费电影| 久久91精品国产| 亚洲搞黄视频| 精品无人区乱码1区2区3区在线| 97超碰中文字幕| 精品久久久久久国产91| 欧美卡一卡二卡三| 亚洲国产精品av| 三级电影在线看| 国产成人精品免费视频网站| 九九九在线观看视频| 在线免费观看欧美| 玖玖精品在线视频| 欧美综合另类| 欧美不卡三区| 国产精品zjzjzj在线观看| 国产成人精品午夜| 日本h片在线观看| 欧美高清电影在线看| 久久日韩视频| 正在播放亚洲1区| 日产精品久久久久久久性色| 日韩久久久精品| 国内精品久久久久久久久久久| 欧美三级日韩三级| 7799精品视频天天看| 精品国产91久久久| 欧美日韩黄色网| 欧美国产一区二区在线观看| 国产全是老熟女太爽了| 99re这里只有精品6| 免费人成视频在线播放| 国产一区二区不卡老阿姨| 青青草原国产在线视频| 免费人成黄页网站在线一区二区 | 国产精品久久久免费观看| 国产成人综合在线播放| 中文字幕色网站| 另类欧美日韩国产在线| 15—17女人毛片| 美腿丝袜亚洲一区| 一区二区xxx| 久久成人久久爱| 啊啊啊国产视频| 免费观看成人鲁鲁鲁鲁鲁视频| 国产a级一级片| 日韩制服丝袜先锋影音| 免费在线观看毛片网站| 蜜乳av一区二区三区| 日本不卡一区二区在线观看| 久久精品99久久久| wwwwwxxxx日本| 国产在线精品一区二区夜色| 黄色a级三级三级三级| 国产精品1区2区| 精品人妻二区中文字幕| av亚洲精华国产精华| 国产熟女高潮一区二区三区 | 日本在线视频网址| 久久久久久高潮国产精品视| av日韩国产| 欧美最猛黑人xxxx黑人猛叫黄| 深夜成人影院| 成人激情视频免费在线| 少妇精品在线| 九色综合日本| 成人在线免费视频观看| 五月天综合网| 天天射天天综合网| 国产乱子伦精品无码专区| 国产精品一区毛片| 538在线视频观看| 国产精品99久久久久久似苏梦涵| 在线观看免费视频国产| 国产日韩在线不卡| 成人性生活毛片| 欧美午夜www高清视频| 中文字幕观看在线| 欧美日韩在线播放三区四区| a天堂在线视频| 亚洲欧美精品一区| caopen在线视频| 欧美亚洲另类在线| 亚洲免费看片| 国模精品娜娜一二三区| av在线不卡顿| 99国产精品白浆在线观看免费| 噜噜噜躁狠狠躁狠狠精品视频| 亚洲天堂2018av| 国产凹凸在线观看一区二区| 久久久精品人妻无码专区| |精品福利一区二区三区| 日本视频免费在线| 8x福利精品第一导航| 污污网站免费在线观看| 久久精品国产综合| 自拍视频在线看| 97久久夜色精品国产九色| 国产欧美日韩精品一区二区三区| 日韩人妻精品一区二区三区| 在线亚洲国产精品网站| 欧美日韩中文不卡| k8久久久一区二区三区| 青青草在线观看视频| 欧美亚洲高清一区| 天堂av2024| 九九精品在线播放| 久久精品超碰| 国产精品亚洲综合| 久久久久久久久99精品大| www日韩在线观看| 91在线国内视频| 精品视频一区二区在线观看| 欧美日韩情趣电影| 国产在线观看网站| 91禁外国网站| www.国产精品一区| 熟女视频一区二区三区| 日本人妖一区二区| jlzzjizz在线播放观看| 亚洲另类在线一区| 91成年人视频| 中文字幕在线视频日韩| 六月婷婷综合| 欧美精品一区在线| 99精品国产一区二区青青牛奶| 99热这里只有精品2| 亚洲视频1区2区| 97精品久久人人爽人人爽| 亚洲视频第一页| 日韩色淫视频| 亚洲精品不卡| 日本成人在线一区| 69精品无码成人久久久久久| 日韩欧美国产成人| 欧美日本韩国一区二区| 777精品视频| 日韩大尺度在线观看| 鲁一鲁一鲁一鲁一色| 国产精品系列在线播放| 精品99在线观看| 精品国产制服丝袜高跟| 免费在线观看的电影网站| 国产传媒一区| 亚洲第一精品影视| 中文字幕乱码在线| 精品动漫一区二区| 毛片在线播放网址| 日韩av电影中文字幕| 你懂的一区二区三区| 国产v亚洲v天堂无码久久久| 国产视频在线观看一区二区三区 | 亚洲五码中文字幕| 肥臀熟女一区二区三区| 久久琪琪电影院| 欧美影院天天5g天天爽| 干日本少妇首页| 日本一区二区三区四区| 一区二区日韩视频| 精品中文字幕在线2019| 欧美一区自拍| 免费看涩涩视频| 一区二区三区欧美| 天天综合网在线观看| 国产精品扒开腿做| 午夜欧美在线| 污污免费在线观看| 一本久久a久久免费精品不卡| 成年人在线观看网站| 国产精品欧美日韩久久| 欧美午夜不卡| 亚洲a v网站| 91精品国模一区二区三区| bl视频在线免费观看| 欧美高清一区二区| 精品一区二区三区视频在线观看 | 亚洲第一福利一区| 极品美乳网红视频免费在线观看 | 88久久精品| 韩国日本在线视频| 亚洲精品国产a久久久久久|