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

SpringBoot 如何保證接口安全?老鳥們都是這么玩的!

網(wǎng)絡(luò) 網(wǎng)絡(luò)管理
我們知道http 是一種無(wú)狀態(tài)的協(xié)議,服務(wù)端并不知道客戶端發(fā)送的請(qǐng)求是否合法,也并不知道請(qǐng)求中的參數(shù)是否正確。

大家好,我是飄渺。

對(duì)于互聯(lián)網(wǎng)來(lái)說(shuō),只要你系統(tǒng)的接口暴露在外網(wǎng),就避免不了接口安全問題。如果你的接口在外網(wǎng)裸奔,只要讓知道接口的地址和參數(shù)就可以調(diào)用,那簡(jiǎn)直就是災(zāi)難。

舉個(gè)例子:你的網(wǎng)站用戶注冊(cè)的時(shí)候,需要填寫手機(jī)號(hào),發(fā)送手機(jī)驗(yàn)證碼,如果這個(gè)發(fā)送驗(yàn)證碼的接口沒有經(jīng)過(guò)特殊安全處理,那這個(gè)短信接口早就被人盜刷不知道浪費(fèi)多少錢了。

那如何保證接口安全呢?

一般來(lái)說(shuō),暴露在外網(wǎng)的api接口需要做到防篡改和防重放才能稱之為安全的接口。

防篡改

我們知道http 是一種無(wú)狀態(tài)的協(xié)議,服務(wù)端并不知道客戶端發(fā)送的請(qǐng)求是否合法,也并不知道請(qǐng)求中的參數(shù)是否正確。

舉個(gè)例子, 現(xiàn)在有個(gè)充值的接口,調(diào)用后可以給用戶增加對(duì)應(yīng)的余額。

http://localhost/api/user/recharge?user_id=1001&amount=10

如果非法用戶通過(guò)抓包獲取到接口參數(shù)后,修改user_id 或 amount的值就可以實(shí)現(xiàn)給任意賬戶添加余額的目的。

如何解決

采用https協(xié)議可以將傳輸?shù)拿魑倪M(jìn)行加密,但是黑客仍然可以截獲傳輸?shù)臄?shù)據(jù)包,進(jìn)一步偽造請(qǐng)求進(jìn)行重放攻擊。如果黑客使用特殊手段讓請(qǐng)求方設(shè)備使用了偽造的證書進(jìn)行通信,那么https加密的內(nèi)容也會(huì)被解密。

一般的做法有2種:

  1. 采用https方式把接口的數(shù)據(jù)進(jìn)行加密傳輸,即便是被黑客破解,黑客也花費(fèi)大量的時(shí)間和精力去破解。
  2. 接口后臺(tái)對(duì)接口的請(qǐng)求參數(shù)進(jìn)行驗(yàn)證,防止被黑客篡改;

圖片

  • 步驟1:客戶端使用約定好的秘鑰對(duì)傳輸?shù)膮?shù)進(jìn)行加密,得到簽名值sign1,并且將簽名值也放入請(qǐng)求的參數(shù)中,發(fā)送請(qǐng)求給服務(wù)端
  • 步驟2:服務(wù)端接收到客戶端的請(qǐng)求,然后使用約定好的秘鑰對(duì)請(qǐng)求的參數(shù)再次進(jìn)行簽名,得到簽名值sign2。
  • 步驟3:服務(wù)端比對(duì)sign1和sign2的值,如果不一致,就認(rèn)定為被篡改,非法請(qǐng)求。

防重放

防重放也叫防復(fù)用。簡(jiǎn)單來(lái)說(shuō)就是我獲取到這個(gè)請(qǐng)求的信息之后什么也不改,,直接拿著接口的參數(shù) 重復(fù)請(qǐng)求這個(gè)充值的接口。此時(shí)我的請(qǐng)求是合法的, 因?yàn)樗袇?shù)都是跟合法請(qǐng)求一模一樣的。重放攻擊會(huì)造成兩種后果:

  1. 針對(duì)插入數(shù)據(jù)庫(kù)接口:重放攻擊,會(huì)出現(xiàn)大量重復(fù)數(shù)據(jù),甚至垃圾數(shù)據(jù)會(huì)把數(shù)據(jù)庫(kù)撐爆。
  2. 針對(duì)查詢的接口:黑客一般是重點(diǎn)攻擊慢查詢接口,例如一個(gè)慢查詢接口1s,只要黑客發(fā)起重放攻擊,就必然造成系統(tǒng)被拖垮,數(shù)據(jù)庫(kù)查詢被阻塞死。

對(duì)于重放攻擊一般有兩種做法:

基于timestamp的方案

每次HTTP請(qǐng)求,都需要加上timestamp參數(shù),然后把timestamp和其他參數(shù)一起進(jìn)行數(shù)字簽名。因?yàn)橐淮握5腍TTP請(qǐng)求,從發(fā)出到達(dá)服務(wù)器一般都不會(huì)超過(guò)60s,所以服務(wù)器收到HTTP請(qǐng)求之后,首先判斷時(shí)間戳參數(shù)與當(dāng)前時(shí)間比較,是否超過(guò)了60s,如果超過(guò)了則認(rèn)為是非法請(qǐng)求。

一般情況下,黑客從抓包重放請(qǐng)求耗時(shí)遠(yuǎn)遠(yuǎn)超過(guò)了60s,所以此時(shí)請(qǐng)求中的timestamp參數(shù)已經(jīng)失效了。如果黑客修改timestamp參數(shù)為當(dāng)前的時(shí)間戳,則sign1參數(shù)對(duì)應(yīng)的數(shù)字簽名就會(huì)失效,因?yàn)楹诳筒恢篮灻罔€,沒有辦法生成新的數(shù)字簽名。

圖片

但是這種方式的漏洞也是顯而易見,如果在60s之內(nèi)進(jìn)行重放攻擊,那就沒辦法了,所以這種方式不能保證請(qǐng)求僅一次有效。

圖片

老鳥們一般會(huì)采取下面這種方案,既可以解決接口重放問題,又可以解決接口一次請(qǐng)求有效的問題。

基于nonce + timestamp 的方案

nonce的意思是僅一次有效的隨機(jī)字符串,要求每次請(qǐng)求時(shí)該參數(shù)要保證不同。實(shí)際使用用戶信息+時(shí)間戳+隨機(jī)數(shù)等信息做個(gè)哈希之后,作為nonce參數(shù)。

此時(shí)服務(wù)端的處理流程如下:

  1. 去 redis 中查找是否有 key 為 nonce:{nonce} 的 string
  2. 如果沒有,則創(chuàng)建這個(gè) key,把這個(gè) key 失效的時(shí)間和驗(yàn)證 timestamp 失效的時(shí)間一致,比如是 60s。
  3. 如果有,說(shuō)明這個(gè) key 在 60s 內(nèi)已經(jīng)被使用了,那么這個(gè)請(qǐng)求就可以判斷為重放請(qǐng)求。

圖片

這種方案nonce和timestamp參數(shù)都作為簽名的一部分傳到后端,基于timestamp方案可以讓黑客只能在60s內(nèi)進(jìn)行重放攻擊,加上nonce隨機(jī)數(shù)以后可以保證接口只能被調(diào)用一次,可以很好的解決重放攻擊問題。

代碼實(shí)現(xiàn)

接下來(lái)通過(guò)實(shí)際代碼來(lái)看看如何實(shí)現(xiàn)接口的防篡改和防重放。

1、構(gòu)建請(qǐng)求頭對(duì)象

@Data
@Builder
public class RequestHeader {
private String sign ;
private Long timestamp ;
private String nonce;
}

2、工具類從HttpServletRequest獲取請(qǐng)求參數(shù)

@Slf4j
@UtilityClass
public class HttpDataUtil {
/**
* post請(qǐng)求處理:獲取 Body 參數(shù),轉(zhuǎn)換為SortedMap
*
* @param request
*/
public SortedMap<String, String> getBodyParams(final HttpServletRequest request) throws IOException {
byte[] requestBody = StreamUtils.copyToByteArray(request.getInputStream());
String body = new String(requestBody);
return JsonUtil.json2Object(body, SortedMap.class);
}


/**
* get請(qǐng)求處理:將URL請(qǐng)求參數(shù)轉(zhuǎn)換成SortedMap
*/
public static SortedMap<String, String> getUrlParams(HttpServletRequest request) {
String param = "";
SortedMap<String, String> result = new TreeMap<>();

if (StringUtils.isEmpty(request.getQueryString())) {
return result;
}

try {
param = URLDecoder.decode(request.getQueryString(), "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}

String[] params = param.split("&");
for (String s : params) {
String[] array=s.split("=");
result.put(array[0], array[1]);
}
return result;
}
}

這里的參數(shù)放入SortedMap中對(duì)其進(jìn)行字典排序,前端構(gòu)建簽名時(shí)同樣需要對(duì)參數(shù)進(jìn)行字典排序。

3、簽名驗(yàn)證工具類

@Slf4j
@UtilityClass
public class SignUtil {
/**
* 驗(yàn)證簽名
* 驗(yàn)證算法:把timestamp + JsonUtil.object2Json(SortedMap)合成字符串,然后MD5
*/
@SneakyThrows
public boolean verifySign(SortedMap<String, String> map, RequestHeader requestHeader) {
String params = requestHeader.getNonce() + requestHeader.getTimestamp() + JsonUtil.object2Json(map);
return verifySign(params, requestHeader);
}

/**
* 驗(yàn)證簽名
*/
public boolean verifySign(String params, RequestHeader requestHeader) {
log.debug("客戶端簽名: {}", requestHeader.getSign());
if (StringUtils.isEmpty(params)) {
return false;
}
log.info("客戶端上傳內(nèi)容: {}", params);
String paramsSign = DigestUtils.md5DigestAsHex(params.getBytes()).toUpperCase();
log.info("客戶端上傳內(nèi)容加密后的簽名結(jié)果: {}", paramsSign);
return requestHeader.getSign().equals(paramsSign);
}
}

4、HttpServletRequest包裝類

public class SignRequestWrapper extends HttpServletRequestWrapper {
//用于將流保存下來(lái)
private byte[] requestBody = null;

public SignRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
requestBody = StreamUtils.copyToByteArray(request.getInputStream());
}

@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream bais = new ByteArrayInputStream(requestBody);

return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}

@Override
public boolean isReady() {
return false;
}

@Override
public void setReadListener(ReadListener readListener) {

}

@Override
public int read() throws IOException {
return bais.read();
}
};

}

@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
}

防篡改和防重放我們會(huì)通過(guò)SpringBoot Filter來(lái)實(shí)現(xiàn),而編寫的filter過(guò)濾器需要讀取request數(shù)據(jù)流,但是request數(shù)據(jù)流只能讀取一次,需要自己實(shí)現(xiàn)HttpServletRequestWrapper對(duì)數(shù)據(jù)流包裝,目的是將request流保存下來(lái)。

5、創(chuàng)建過(guò)濾器實(shí)現(xiàn)安全校驗(yàn)

@Configuration
public class SignFilterConfiguration {
@Value("${sign.maxTime}")
private String signMaxTime;

//filter中的初始化參數(shù)
private Map<String, String> initParametersMap = new HashMap<>();

@Bean
public FilterRegistrationBean contextFilterRegistrationBean() {
initParametersMap.put("signMaxTime",signMaxTime);
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(signFilter());
registration.setInitParameters(initParametersMap);
registration.addUrlPatterns("/sign/*");
registration.setName("SignFilter");
// 設(shè)置過(guò)濾器被調(diào)用的順序
registration.setOrder(1);
return registration;
}

@Bean
public Filter signFilter() {
return new SignFilter();
}
}
@Slf4j
public class SignFilter implements Filter {
@Resource
private RedisUtil redisUtil;

//從fitler配置中獲取sign過(guò)期時(shí)間
private Long signMaxTime;

private static final String NONCE_KEY = "x-nonce-";

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;

log.info("過(guò)濾URL:{}", httpRequest.getRequestURI());

HttpServletRequestWrapper requestWrapper = new SignRequestWrapper(httpRequest);
//構(gòu)建請(qǐng)求頭
RequestHeader requestHeader = RequestHeader.builder()
.nonce(httpRequest.getHeader("x-Nonce"))
.timestamp(Long.parseLong(httpRequest.getHeader("X-Time")))
.sign(httpRequest.getHeader("X-Sign"))
.build();

//驗(yàn)證請(qǐng)求頭是否存在
if(StringUtils.isEmpty(requestHeader.getSign()) || ObjectUtils.isEmpty(requestHeader.getTimestamp()) || StringUtils.isEmpty(requestHeader.getNonce())){
responseFail(httpResponse, ReturnCode.ILLEGAL_HEADER);
return;
}

/*
* 1.重放驗(yàn)證
* 判斷timestamp時(shí)間戳與當(dāng)前時(shí)間是否操過(guò)60s(過(guò)期時(shí)間根據(jù)業(yè)務(wù)情況設(shè)置),如果超過(guò)了就提示簽名過(guò)期。
*/
long now = System.currentTimeMillis() / 1000;

if (now - requestHeader.getTimestamp() > signMaxTime) {
responseFail(httpResponse,ReturnCode.REPLAY_ERROR);
return;
}

//2. 判斷nonce
boolean nonceExists = redisUtil.hasKey(NONCE_KEY + requestHeader.getNonce());
if(nonceExists){
//請(qǐng)求重復(fù)
responseFail(httpResponse,ReturnCode.REPLAY_ERROR);
return;
}else {
redisUtil.set(NONCE_KEY+requestHeader.getNonce(), requestHeader.getNonce(), signMaxTime);
}


boolean accept;
SortedMap<String, String> paramMap;
switch (httpRequest.getMethod()){
case "GET":
paramMap = HttpDataUtil.getUrlParams(requestWrapper);
accept = SignUtil.verifySign(paramMap, requestHeader);
break;
case "POST":
paramMap = HttpDataUtil.getBodyParams(requestWrapper);
accept = SignUtil.verifySign(paramMap, requestHeader);
break;
default:
accept = true;
break;
}
if (accept) {
filterChain.doFilter(requestWrapper, servletResponse);
} else {
responseFail(httpResponse,ReturnCode.ARGUMENT_ERROR);
return;
}

}

private void responseFail(HttpServletResponse httpResponse, ReturnCode returnCode) {
ResultData<Object> resultData = ResultData.fail(returnCode.getCode(), returnCode.getMessage());
WebUtils.writeJson(httpResponse,resultData);
}

@Override
public void init(FilterConfig filterConfig) throws ServletException {
String signTime = filterConfig.getInitParameter("signMaxTime");
signMaxTime = Long.parseLong(signTime);
}
}

6、Redis工具類

@Component
public class RedisUtil {
@Resource
private RedisTemplate<String, Object> redisTemplate;

/**
* 判斷key是否存在
* @param key 鍵
* @return true 存在 false不存在
*/
public boolean hasKey(String key) {
try {
return Boolean.TRUE.equals(redisTemplate.hasKey(key));
} catch (Exception e) {
e.printStackTrace();
return false;
}
}


/**
* 普通緩存放入并設(shè)置時(shí)間
* @param key 鍵
* @param value 值
* @param time 時(shí)間(秒) time要大于0 如果time小于等于0 將設(shè)置無(wú)限期
* @return true成功 false 失敗
*/
public boolean set(String key, Object value, long time) {
try {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}

/**
* 普通緩存放入
* @param key 鍵
* @param value 值
* @return true成功 false失敗
*/
public boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}

}


責(zé)任編輯:武曉燕 來(lái)源: JAVA日知錄
相關(guān)推薦

2023-04-12 08:56:37

RocketMQSpring核心業(yè)務(wù)

2023-11-23 08:25:31

String性能

2021-07-16 08:58:35

SpringBoot

2021-05-26 08:49:15

API接口安全

2025-09-05 07:42:19

Spring接口監(jiān)控

2023-10-16 11:12:29

2025-08-18 07:35:40

2024-03-06 08:36:36

2025-08-13 01:11:00

2024-11-27 08:47:12

2023-01-26 02:07:51

HashSet線程安全

2022-10-31 08:47:21

人臉識(shí)別按鍵鍵盤

2022-07-04 07:41:53

接口數(shù)據(jù)安全

2024-06-17 00:02:00

線程安全HashMapJDK 1.7

2011-09-23 10:13:43

2017-11-03 13:48:59

ERP信息化數(shù)據(jù)

2024-05-06 13:36:41

2020-11-26 12:40:26

NTSNTP系統(tǒng)運(yùn)維

2019-03-13 08:28:28

物聯(lián)網(wǎng)設(shè)計(jì)物聯(lián)網(wǎng)安全物聯(lián)網(wǎng)

2016-12-26 09:50:15

點(diǎn)贊
收藏

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

亚洲第一网站男人都懂| 亚洲欧美日韩在线| 欧美怡红院视频一区二区三区| 手机av免费看| 日韩高清成人| 亚洲精品乱码久久久久久黑人| 国产精品美女诱惑| 最近中文字幕av| 欧美激情在线| 亚洲人成亚洲人成在线观看| 污视频在线观看免费网站| 精品极品在线| 国产精品高潮久久久久无| 官网99热精品| 91国内精品久久久| 免费在线欧美黄色| 欧美成人h版在线观看| 国产交换配乱淫视频免费| 日韩中文字幕在线一区| 色综合久久久网| 日本人妻伦在线中文字幕| 国产一级免费在线观看| 成人免费毛片aaaaa**| 国产精品综合不卡av| 成人在线免费看视频| 欧美久久99| 日韩亚洲国产中文字幕| 国产全是老熟女太爽了| 乱亲女h秽乱长久久久| 欧美美女直播网站| 日韩欧美xxxx| 中文在线аv在线| 亚洲第一在线综合网站| 中文字幕在线乱| av在线免费观看网站| 26uuu国产在线精品一区二区| 国产99午夜精品一区二区三区| 国产精品高潮呻吟久久久| 久久精品一区| 日本精品一区二区三区在线播放视频 | 亚洲欧美综合另类| 亚洲激情视频| 久久免费精品视频| 69av.com| 欧美精品99| 美日韩精品免费视频| 国产精品免费在线视频| 欧美r级电影| 中文字幕欧美日韩在线| av女人的天堂| 国产欧美一区| 国产一区二区三区免费视频| 91中文字幕永久在线| 亚洲三级精品| 亚洲老头同性xxxxx| 日韩av一二区| 曰本一区二区三区视频| 亚洲老头老太hd| 人妻视频一区二区| 成人精品视频| 日韩视频在线观看免费| 在线免费看av网站| 欧美日韩蜜桃| 97久久精品国产| 中文字幕激情小说| 免费在线欧美视频| 成人午夜小视频| 亚洲xxxx天美| www.欧美日韩国产在线| 裸体丰满少妇做受久久99精品| 青青九九免费视频在线| 欧美激情一区二区三区蜜桃视频| 亚洲精品高清国产一线久久| 日本免费中文字幕在线| 一区二区三区**美女毛片| 日韩一级性生活片| 自拍偷拍亚洲视频| 欧美日韩精品三区| 一卡二卡三卡四卡五卡| 日韩美女国产精品| 亚洲最新av网址| 亚洲天堂网av在线| 激情欧美一区| 日韩中文字幕一区二区| av免费观看网址| 国产精品中文字幕日韩精品| 成人在线视频电影| 日本中文字幕电影在线观看| 中文字幕欧美激情| 国产在线无码精品| 性欧美xxx69hd高清| 欧美色综合网站| 久久久久99人妻一区二区三区| 欧美黄色录像| 色悠悠久久久久| 久久久久无码国产精品| 日韩精品一卡二卡三卡四卡无卡| 国产精品影院在线观看| 亚洲精品视频专区| 欧美国产精品久久| www.九色.com| 涩涩涩久久久成人精品| 日韩av在线免播放器| 可以免费看av的网址| 亚洲另类自拍| 91精品免费视频| 日韩精品视频无播放器在线看| 国产精品二三区| 黄色一级片播放| 精品视频一区二区三区在线观看| 国产婷婷色综合av蜜臀av| 99视频只有精品| 日韩国产高清在线| 精品国产福利| sm国产在线调教视频| 色欲综合视频天天天| 亚洲美女精品视频| xxxx日韩| 久久99精品久久久久久琪琪| www.av88| 久久久亚洲精品一区二区三区| 天天想你在线观看完整版电影免费 | 成人国产精品免费网站| 在线免费一区| 爱爱视频免费在线观看| 国产在线视频资源| 亚洲国产精品久久不卡毛片| 蜜桃福利午夜精品一区| 精品成人影院| 97视频色精品| 国产91免费看| 亚洲乱码国产乱码精品精98午夜| 色婷婷综合久久久久中文字幕| 大桥未久女教师av一区二区| 久久香蕉国产线看观看av| 在线观看毛片视频| 中文幕一区二区三区久久蜜桃| 国产主播在线看| 欧美日韩精品一区二区三区在线观看| 欧美肥婆姓交大片| 国产成人久久精品77777综合 | 东方伊人免费在线观看| 免费亚洲网站| 欧美性xxxx69| 日韩电影av| 亚洲人成伊人成综合网久久久| 91九色丨porny丨肉丝| 99在线精品一区二区三区| 日韩精品视频在线观看视频| 精品网站999| 欧美老女人性视频| 亚洲av无码一区二区三区dv| 亚洲午夜国产一区99re久久| 一级黄色片毛片| 亚洲国产高清一区| 精品在线不卡| 精品视频一区二区三区四区五区| 国产一区二区三区丝袜| 一区二区三区在线免费观看视频| 国产日韩精品久久久| 超碰在线人人爱| 亚洲成人av| 国产高清自拍一区| 三级在线看中文字幕完整版| 亚洲欧洲在线播放| 中文字幕一区二区三区免费看| 国产精品久久久久久久蜜臀| 亚洲av无日韩毛片久久| 欧美日韩国内| 欧美一区1区三区3区公司 | 久久av在线| 日韩欧美亚洲v片| 亚洲aⅴ网站| 精品中文字幕在线观看| 天堂在线视频观看| 欧美伊人久久久久久午夜久久久久| 久久久久亚洲AV成人无在 | 色婷婷激情久久| 三级黄色在线观看| av电影在线观看完整版一区二区| 爱福利视频一区二区| 欧美超碰在线| 国产另类第一区| 国产91精品在线| 欧美激情一区二区三区在线视频观看 | 好吊操这里只有精品| 国产亚洲成aⅴ人片在线观看| 亚洲a级黄色片| 国产欧美日韩综合一区在线播放| 日韩精品无码一区二区三区| 天堂av一区| 国产成人精品视频| 乱插在线www| 永久免费看mv网站入口亚洲| 丰满人妻妇伦又伦精品国产| 欧美中文字幕不卡| 久久精品无码人妻| 国产精品女主播av| avtt香蕉久久| 国产乱码精品一区二区三| 欧美精品99久久| **女人18毛片一区二区| 欧美日韩国产综合视频在线| 伊人精品综合| 国产精品视频大全| 成人免费网站观看| 久久国产精品久久久久久| 欧美精品少妇| 精品国产人成亚洲区| 在线观看色网站| 欧美日韩在线视频一区| 国产性xxxx| 国产精品女人毛片| 亚洲国产日韩一区无码精品久久久| 国产精品一区免费视频| 日本黄大片一区二区三区| 性一交一乱一区二区洋洋av| 精品免费久久久久久久| 999久久久精品国产| 日本午夜精品一区二区| 日韩影视高清在线观看| 成人永久免费| 玖玖玖视频精品| 国产精品永久免费观看| 精品成人免费一区二区在线播放| 97av在线视频| 9999在线视频| 欧美精品久久一区二区| 色呦呦在线看| 免费av一区二区| 麻豆传媒在线观看| 日韩中文字幕视频| 亚洲1卡2卡3卡4卡乱码精品| 亚洲欧美日韩中文视频| 亚州男人的天堂| 亚洲国产精品久久| 国产77777| 亚洲成人av片在线观看| 亚洲经典一区二区三区| 日韩视频免费观看高清在线视频| 国产露脸91国语对白| 在线91免费看| 国产精品久久久久久久久久久久久久久久久久 | 日本成人黄色网| 日韩福利电影在线观看| 乱子伦视频在线看| 日韩激情在线观看| 污版视频在线观看| 精品一区二区日韩| 黄色a级三级三级三级| 国产老肥熟一区二区三区| 亚洲一区二区三区四区精品| 国精品**一区二区三区在线蜜桃| 日本中文字幕二区| 国产精品99久久不卡二区| 人妻巨大乳一二三区| 成人在线一区二区三区| 日韩少妇一区二区| 91女厕偷拍女厕偷拍高清| 精品人妻一区二区三区视频| 国产欧美一区二区精品秋霞影院 | 国产精品video| 成人在线观看免费视频| 成人激情黄色网| 操欧美女人视频| 免费毛片一区二区三区久久久| 国产精品欧美日韩一区| 亚洲一区二区三区精品视频| 91精品1区| 国产精品12345| 日韩成人一级片| 中文字幕在线视频一区二区三区| 国产成人亚洲精品青草天美| 五十路六十路七十路熟婆| 久久精品欧美日韩精品| 一起操在线播放| 午夜成人在线视频| 中文字幕 日韩有码| 欧美一区二区三级| 欧洲免费在线视频| 精品国产一区二区三区在线观看| 美女日批视频在线观看| 国产不卡在线观看| 日本一区精品视频| 蜜桃视频日韩| 午夜片欧美伦| 精品人妻一区二区三区四区在线 | 99精品欧美| 在线观看免费不卡av| 成人精品亚洲人成在线| 非洲一级黄色片| 洋洋av久久久久久久一区| 69亚洲精品久久久蜜桃小说| 制服丝袜一区二区三区| 日本一二三区在线视频| 久久久成人的性感天堂| 在线看片福利| 亚洲精品日韩av| 国产成人短视频在线观看| 国产制服91一区二区三区制服| 久久精品一区二区国产| 久草免费资源站| 国产精品乱子久久久久| 草久久免费视频| 欧美一级理论片| av二区在线| 91高清免费视频| 91成人噜噜噜在线播放| 自拍偷拍99| 日韩国产精品久久久久久亚洲| 2025中文字幕| 亚洲欧洲www| 无码人妻av免费一区二区三区| 欧美mv日韩mv国产网站app| av播放在线| 日韩av成人在线观看| 操欧美女人视频| 女女百合国产免费网站| 看电视剧不卡顿的网站| 久久只有这里有精品| 午夜精品成人在线| 亚洲国产精品一| 久久资源免费视频| 亚洲精品aaa| 亚洲亚洲精品三区日韩精品在线视频| 免费看黄裸体一级大秀欧美| 免费a v网站| 亚洲国产成人va在线观看天堂| 国产视频在线一区| 久久九九全国免费精品观看| 玖玖精品在线| 亚洲一卡二卡区| 老司机精品视频一区二区三区| 亚洲综合欧美综合| 日本精品视频一区二区| 欧美扣逼视频| 国产成人精品av在线| 九一精品国产| 国产男女无遮挡| 国产女主播在线一区二区| 亚洲乱码国产乱码精品| 亚洲人成在线电影| 99久久精品一区二区成人| 色综合视频二区偷拍在线| 日韩中文字幕亚洲一区二区va在线| 老鸭窝一区二区| 色视频成人在线观看免| 国产在线电影| 国产精品天天狠天天看| 波多野结衣的一区二区三区 | 超薄肉色丝袜足j调教99| 国产麻豆一精品一av一免费| 国内偷拍精品视频| 日韩免费一区二区| 搞黄网站在线看| 精品免费视频123区| 国产精品久久久一区二区| 国产色视频一区二区三区qq号| 色香蕉成人二区免费| sese一区| 亚洲综合精品伊人久久| 亚洲高清av| 成都免费高清电影| 欧美人妇做爰xxxⅹ性高电影 | 天天操天天干天天操| 国产91成人在在线播放| 精品久久久久久久久久久下田 | 91麻豆精品一二三区在线| 国产911在线观看| jiyouzz国产精品久久| 免费污污视频在线观看| 尤物yw午夜国产精品视频明星| 国产精品视频一区二区三区综合| 大陆极品少妇内射aaaaaa| www.爱久久.com| 亚洲 国产 日韩 欧美| 久久久国产91| 日韩高清一级| 最新免费av网址| 亚洲成人激情av| 电影av在线| 99精品99久久久久久宅男| 免费一区视频| 日韩激情综合网| 日韩精品中文字| 成人动漫视频在线观看| 日韩av在线播放不卡| 中文字幕av一区二区三区免费看 | 久草手机在线观看| 日韩三级成人av网| 亚洲传媒在线| 欧美激情第四页| 在线看一区二区| heyzo一区| 亚洲国产精品影视| www久久久久| www.色视频| 国产精品香蕉av| 国产一区二区三区的电影| 少妇被躁爽到高潮无码文|