久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

springBoot-springSecurity-OAuth2

 jacklopy 2024-10-30

目錄

一、概述

1,、OAuth2基本概念可以參考 OAuth2.0最簡向導 ()

2,、OAuth2 主要流程

3、OAuth2 應用場景

4,、OAuth2 授權模式(4種)

二,、使用

1、導入maven依賴

2,、配置資源服務器

   1.編寫controller類 

    2.編寫資源服務器配置文件

3,、配置授權服務器

1.授權碼模式

        1.1 配置授權服務器

        1.2 配置springSecurity登錄賬號

        1.3 啟動項目獲取授權碼

        1.4 獲取令牌token

        1.5 調用資源服務器api

        1.6 項目整體結構

2.密碼模式

1.1 配置授權服務器

?編輯

1.2 配置springSecurity登錄賬號

1.3 啟動項目

1.4 獲取令牌token

1.5 調用資源服務器api

1.6 項目整體結構

3.簡化模式

1.1 配置授權服務器

1.2 配置springSecurity登錄賬號

1.3 啟動項目

1.4 獲取令牌token

1.5 調用資源服務器api

1.6 項目整體結構

4.客戶端模式

1.1 配置授權服務器

1.2 配置springSecurity登錄賬號

1.3 啟動項目

1.4 獲取令牌token

1.5 調用資源服務器api

1.6 項目整體結構

三,、四種模式總結:

1、 總結

2,、 為什么有 Client 賬號和密碼,?

四、刷新token

1,、獲取token及刷新token 

2,、通過刷新token獲取新token

3,、項目整體結構

五,、刪除token

1,、新建刪除令牌token接口

2,、資源服務器配置修改

3、啟動項目

4,、獲取token

5、調用刪除token接口

6,、項目整體結構

六,、刪除刷新token

1、注入TokenStore

2,、新建刪除刷新token接口

2,、資源服務器配置修改

3、啟動項目

4,、獲取token及刷新token

5,、調用刪除刷新token接口

6、項目整體結構

一,、概述

        OAuth2是一個授權框架。用來授權第三方應用獲取數(shù)據(jù),,是目前最流行的授權機制,。

1、OAuth2基本概念可以參考 OAuth2.0最簡向導 ()

2,、OAuth2 主要流程

  1. 用戶在客戶應用點擊第三方應用,,請求第三方應用授權訪問。
  2. 第三方應用授權服務器同意客戶應用授權,,返回授權碼,。
  3. 客戶應用使用授權碼向授權服務器申請令牌(token),。
  4. 授權服務器對客戶應用進行身份驗證,驗證通過后發(fā)放令牌(token),。
  5. 客戶應用就可以帶著這個令牌(token),,去訪問資源服務器的api。
  6. 資源服務器校驗客戶應用帶著的令牌(token),,校驗通過,,返回訪問的api數(shù)據(jù)信息。

3,、OAuth2 應用場景

        網(wǎng)易云第三方登錄(QQ,、微信、微博等),。實際生活當中許多地方都會用到第三方登錄,,進行授權后,對其資源進行訪問,。

用戶請求第三方應用進行授權

實際的流程如下:

4,、OAuth2 授權模式(4種)

OAuth 協(xié)議的授權模式共分為 4 種,分別說明如下:

  • 授權碼模式:授權碼模式(authorization code)是功能最完整,、流程最嚴謹?shù)氖跈嗄J?。它的特點就是通過客戶端的服務器與授權服務器進行交互,國內常見的第三方平臺登錄功能基本都是使用這種模式,。(最正統(tǒng)的方式,,也是目前絕大多數(shù)系統(tǒng)所采用的)(支持refresh token) (用在服務端應用之間)

  • 簡化模式:簡化模式不需要客戶端服務器參與,直接在瀏覽器中向授權服務器中請令牌,,一般若網(wǎng)站是純靜態(tài)頁面,,則可以采用這種方式。(為web瀏覽器應用設計)(不支持refresh token) (用在移動app或者web app,,這些app是在用戶的設備上的,,如在手機上調起微信來進行認證授權)

  • 密碼模式:密碼模式是用戶把用戶名密碼直接告訴客戶端,客戶端使用這些信息向授權服務器中請令牌,。這需要用戶對客戶端高度信任,例如客戶端應用和服務提供商是同一家公司,。(為遺留系統(tǒng)設計) (支持refresh token)

  • 客戶端模式:客戶端模式是指客戶端使用自己的名義而不是用戶的名義向服務提供者申請授權,。嚴格來說,客戶端模式并不能算作 OAuth 協(xié)議要解決的問題的一種解決方案,,但是,,對于開發(fā)者而言,在一些前后端分離應用或者為移動端提供的認證授權服務器上使用這種模式還是非常方便的,。(為后臺api服務消費者設計) (不支持refresh token) (為后臺api服務消費者設計)

二,、使用

對于 Spring Security OAuth2 的配置,,大體來說,就是兩步

  1. 配置授權服務器( AuthorizationServer )
  2. 配置資源服務器( ResourceServer )

1,、導入maven依賴

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-web</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework.boot</groupId>
  8. <artifactId>spring-boot-starter-security</artifactId>
  9. </dependency>
  10. <dependency>
  11. <groupId>org.springframework.security.oauth</groupId>
  12. <artifactId>spring-security-oauth2</artifactId>
  13. </dependency>
  14. </dependencies>

SpringBoot 的版本為 1.5.16.RELEASE ,,所以使用的 Spring Security 的版本為 4.2.8.RELEASE ,Spring Security OAuth2 的版本為 2.2.0.15.RELEASE 

2,、配置資源服務器

資源服務器一般提供Api服務,,例如訂單、商品服務等,。考慮到讓整個示例更加簡單,,本文先將它和授權服務器放在一個 Maven 項目中

   1.編寫controller類 
  1. /**
  2. * 資源服務器訪問示例
  3. */
  4. @RestController
  5. @RequestMapping("/api")
  6. public class HelloController {
  7. @GetMapping("/hello")
  8. public String hello() {
  9. return "Hello World!";
  10. }
  11. }
    2.編寫資源服務器配置文件
  1. @Configuration
  2. @EnableResourceServer
  3. public class OAuth2ResourceServer extends ResourceServerConfigurerAdapter {
  4. @Override
  5. public void configure(HttpSecurity http) throws Exception {
  6. http.authorizeRequests()
  7. // 對 "/api/**" 開啟認證
  8. .anyRequest()
  9. .authenticated()
  10. .and()
  11. .requestMatchers()
  12. .antMatchers("/api/**");
  13. }
  14. }

@Configuration 注解:保證 OAuth2ResourceServer 能夠被 SpringBoot 掃描到配置,。 @EnableResourceServer 注解:開啟資源服務器,。

                @EnableResourceServer繼承( extends ) ResourceServerConfigurerAdapter 類,并覆寫 #configure(HttpSecurity http) 方法,,配置對 HTTP 請求中,,匹配 /api/**" 路徑,開啟認證的驗證,。( @EnableResourceServer導入了ResourceServerConfiguration配置類,,該配置類繼承了WebSecurityConfigurerAdapter,擁有了http security的相關能力,。 

3,、配置授權服務器

這兒就用到了上面所說的四種授權模式:

  1. 授權碼模式
  2. 簡化模式
  3. 密碼模式
  4. 客戶端模式
1.授權碼模式
        1.1 配置授權服務器
  1. // 授權服務器配置
  2. @Configuration
  3. @EnableAuthorizationServer //開啟授權服務器
  4. public class OAuth2AuthorizationServer extends AuthorizationServerConfigurerAdapter {
  5. @Override
  6. public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
  7. clients.inMemory() // 基于內存,實際當中應該存放數(shù)據(jù)庫
  8. .withClient("mobai").secret("123") // Client 賬號、密碼,。
  9. .redirectUris("http://localhost:9001/callback") // 配置回調地址,,選填。
  10. .authorizedGrantTypes("authorization_code") // 授權碼模式
  11. .scopes("user_info", "role_info"); // 可授權的 Scope
  12. }
        1.2 配置springSecurity登錄賬號

在application.yml中配置springSecurity登錄賬號密碼,。實際當中登錄賬號是放在數(shù)據(jù)庫當中的,。

  1. security:
  2. user:
  3. name: admin
  4. password: admin
        1.3 啟動項目獲取授權碼

訪問  http://localhost:8080/oauth/authorize?client_id=mobai&redirect_uri=http://localhost:9001/callback&response_type=code&scope=user_info 獲取

-client_id :必傳,為我們在 OAuth2AuthorizationServer 中配置的 Client 的編號,。
 redirect_url :可選,,回調地址。當然,,如果 client_id 對應的 Client 未配置 redirectUris 屬性,,會報錯。實際項目當中,,會在后端編寫一個接收授權碼的接口進行授權碼接收,,或者跳轉到對應的頁面(回調地址)進行授權碼接收,前端進行地址攔截,再進行下一步處理(如登錄),。
response_type :必傳,,返回結果為授權碼。
scope :可選,,申請授權的 Scope ,。如果多個,使用逗號分隔,。
state :  可選,,表示客戶端的當前狀態(tài),可以指定任意值,,認證服務器會原封不動地返回這                個值,。未在上述 URL 中體現(xiàn)出來。

        訪問該地址后,,會跳至 springSecurity 登錄頁面,,輸入上面配置的賬號密碼 admin/amdin,跳至oauth授權確認頁面,,如下:

選擇批準,,進行確認,確認后會返回回調地址及其授權碼。

- code就是返回的授權碼,。

        1.4 獲取令牌token

此處我用postman工具進行請求發(fā)送,。

配置Authorization,OAuth2AuthorizationServer 中配置的 Client 的賬號和密碼(mobai/123),。

配置body,。

- code:上面1.3小結訪問接口獲取到的授權碼。

- grant_type:authorization_code 表示以授權模式獲取token,。

- redirect_uri:http://localhost:9001/callback 這個redirect_uri參數(shù)是客戶端注冊時指定的回調URI,,經(jīng)過URL編碼處理。當授權過程完成時,,用戶會被重定向到這個地址,,并帶上授權碼或其他響應信息。在此處需要確保該URI與之前請求授權時使用的完全一致,。

- scope:user_info  scope參數(shù)定義了客戶端所請求的權限范圍,,本例中是user_info,意味著客戶端希望獲得讀取用戶信息的權限

請求發(fā)送成功返回token等信息,。

- access_token:返回的token,。

- token_type:  令牌類型??梢允?nbsp;"bearer" 或 "mac" 類型。

- expires_in: 過期時間。

- scope: 權限范圍,。如果與 Client 申請的范圍一致,,此項可省略。

- refresh_token:刷新令牌,,用來獲取下一次的訪問令牌,。在授權模式下為空。

注意:授權碼只能使用一次,,再次訪問授權碼失效,。平時項目當中還會將token存放在redis里面。

        1.5 調用資源服務器api

訪問/api/hello 接口

沒有攜帶token時:

攜帶返回的token進行訪問時:

        1.6 項目整體結構

        由于方便測試,,下方resour_serve資源服務器相關代碼放在的授權服務器當中,。實際項目根據(jù)場景編寫代碼。

2.密碼模式

       新建password_serve模塊,,資源服務器的編寫還是和上面的(2、配置資源服務器)一樣,。

1.1 配置授權服務器

        與授權碼模式配置不一樣的是,,此處沒有配置回調地址,并將授權類型改為了密碼模式,,通過賬號和密碼直接獲取令牌token,,省略了授權碼獲取這一步驟

  1. // 授權服務器配置 密碼模式
  2. @Configuration
  3. @EnableAuthorizationServer //開啟授權服務器
  4. public class OAuth2AuthorizationServer extends AuthorizationServerConfigurerAdapter {
  5. // 用戶認證
  6. @Autowired
  7. private AuthenticationManager authenticationManager;
  8. @Override
  9. public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
  10. endpoints.authenticationManager(authenticationManager);
  11. }
  12. @Override
  13. public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
  14. clients.inMemory() // 基于內存,實際當中應該存放數(shù)據(jù)庫
  15. .withClient("mobai").secret("123") // Client 賬號,、密碼,。
  16. .authorizedGrantTypes("password") // 密碼模式
  17. .scopes("user_info", "role_info"); // 可授權的 Scope
  18. }
  19. }

    另外注意的是,密碼模式還需要開啟springSecurity用戶認證支持密碼模式,,不然會報以下錯誤,。

開啟用戶認證

1.2 配置springSecurity登錄賬號

        與授權碼模式,1.2配置springSecurity登錄賬號相同,。

1.3 啟動項目
1.4 獲取令牌token

        填寫客戶端賬號密碼

        填寫請求體body

- grant_type: 授權類型為以密碼模式獲取token

- scope: 客戶端所請求的權限范圍

- username: 配置的springSecurity賬號

- password:  配置的springSecurity密碼

        具體參數(shù)介紹在授權模式下的1.5調用資源服務器api小節(jié)下有講,。

1.5 調用資源服務器api

        與 授權碼模式下1.5調用資源服務器api一樣。

        填寫獲取到token進請求頭,,請求api返回數(shù)據(jù),。

1.6 項目整體結構

3.簡化模式

  新建simply_serve模塊,資源服務器的編寫還是和上面的(2,、配置資源服務器)一樣。

1.1 配置授權服務器

        與授權碼模式配置不一樣的是,,簡化模式(implicit grant type)不通過第三方應用程序的服務器,,直接在瀏覽器中向認證服務器申請令牌token,,跳過了"授權碼"這個步驟,因此得名,。所有步驟在瀏覽器中完成,,令牌對訪問者是可見的,且客戶端不需要認證,。

        簡而言之,,授權碼模式在瀏覽器訪問返回的是授權碼,后續(xù)再通過授權碼獲取令牌token,。而簡化模式在瀏覽器訪問直接返回的是令牌token,可以直接使用,。

        授權服務器配置與授權碼模式大至相同,不同的是授權類型是 implicit 簡化模式,。

  1. // 授權服務器配置 簡化模式
  2. @Configuration
  3. @EnableAuthorizationServer //開啟授權服務器
  4. public class OAuth2AuthorizationServer extends AuthorizationServerConfigurerAdapter {
  5. @Override
  6. public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
  7. clients.inMemory() // 基于內存,實際當中應該存放數(shù)據(jù)庫
  8. .withClient("mobai").secret("123") // Client 賬號,、密碼。
  9. .redirectUris("http://www.baidu.com") // 配置回調地址,,選填,。
  10. .authorizedGrantTypes("implicit") // 簡化模式
  11. .scopes("user_info", "role_info"); // 可授權的 Scope
  12. }
  13. }
1.2 配置springSecurity登錄賬號

        與前面兩種模式相同。

1.3 啟動項目
1.4 獲取令牌token

        在瀏覽器訪問  http://localhost:8080/oauth/authorize?client_id=mobai&redirect_uri=http://www.baidu.com&response_type=token&scope=user_info

- client_id=mobai : 授權服務器配置的客戶端賬號

- redirect_uri=http://www.baidu.com : 配置的回調地址

- response_type=token : 返回類型為token,,而不是授權碼code,。返回code,回調后瀏覽器地址欄會報錯,不知道返回的類型,。

- scope=user_info : 權限范圍,。

訪問過程:

        1.輸入密碼

        2. 授權成功,跳轉至回調地址,,回調地址后會攜帶令牌token,、token類型和過期時間

  • 和【授權碼模式】基本不一致的有兩點
    • 登錄成功后,無需選擇允許所有申請的 Scope ,,直接授權完成,。
    • 返回的不是授權碼,而是訪問令牌token,。

總的來說,,【簡化模式】是【授權碼模式】的簡化模式。

1.5 調用資源服務器api

        和前面兩種模式相同,。

1.6 項目整體結構

4.客戶端模式

         新建client_serve模塊,,資源服務器的編寫還是和上面的(2,、配置資源服務器)一樣,。

1.1 配置授權服務器

        與密碼模式差不多,但區(qū)別是客戶端模式不需要用戶登錄,,不用配置用戶認證,,不要配置回調地址,,授權類型為 client_credentials 客戶端模式。

  1. // 授權服務器配置 客戶端模式
  2. @Configuration
  3. @EnableAuthorizationServer //開啟授權服務器
  4. public class OAuth2AuthorizationServer extends AuthorizationServerConfigurerAdapter {
  5. @Override
  6. public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
  7. clients.inMemory() // 基于內存,實際當中應該存放數(shù)據(jù)庫
  8. .withClient("mobai").secret("123") // Client 賬號,、密碼,。
  9. .authorizedGrantTypes("client_credentials") // 客戶端模式
  10. .scopes("user_info", "role_info"); // 可授權的 Scope
  11. }
  12. }
1.2 配置springSecurity登錄賬號

        它無需配置登錄賬號。因為它沒有用戶的概念,,直接與授權服務器交互,通過 Client 的編號( client_id )和密碼( client_secret )來保證安全性,。

1.3 啟動項目
1.4 獲取令牌token

        1.填寫客戶端賬號密碼

        2.填寫請求體body

        3.結果

        參數(shù)介紹可以參考上面幾種模式

1.5 調用資源服務器api

        和前面幾種模式相同,。

1.6 項目整體結構

三、四種模式總結:

1,、 總結

  總的來說:

【簡化模式】是【授權碼模式】的簡化模式,,【客戶端模式】是【密碼模式】的簡化模式。

授權碼模式: 在瀏覽器需要用戶確認授權,,再訪問獲取授權碼的請求,,再用獲取到的授權碼                        在服務端獲取令牌token,調用api,。

簡化模式: 對比授權碼模式,,省略了獲取授權碼的步驟,在瀏覽器獲取到的直接是令牌                           token,,調用api,。

密碼模式:直接用用戶的登錄密碼,獲取令牌token,,再調用api,。

客戶端模式:對比密碼模式,省略用戶登錄密碼,,只需要驗證客戶端賬號密碼即可,。通過客                       戶端賬號密碼,獲取token,再調用api,。

2,、 為什么有 Client 賬號和密碼?

        從上面四種授權模式,,可以知道,,無論哪種授權模式,都需要傳client的賬號和密碼,。這是因為通過 Client 編號和密碼,,授權服務器可以知道調用的來源以及正確性。這樣,,即使“壞人”拿到 Access Token ,,但是沒有 Client 賬號和密碼,,也不能和授權服務器發(fā)生有效的交互。

四,、刷新token

        由于token有過期時間,,因此我們需要配置refresh_token,對token進行刷新,。

1,、獲取token及刷新token 

下面以密碼模式進行驗證:

        刷新token只需要在授權服務器配置中authorizedGrantTypes后面加上refresh_token,再在參數(shù)鏈后面添加refresh_token的過期時間(refreshTokenValiditySeconds(1200))即可,。

  1. // 授權服務器配置 密碼模式
  2. @Configuration
  3. @EnableAuthorizationServer //開啟授權服務器
  4. public class OAuth2AuthorizationServer extends AuthorizationServerConfigurerAdapter {
  5. // 用戶認證
  6. @Autowired
  7. private AuthenticationManager authenticationManager;
  8. @Override
  9. public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
  10. endpoints.authenticationManager(authenticationManager);
  11. }
  12. @Override
  13. public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
  14. clients.inMemory() // 基于內存,實際當中應該存放數(shù)據(jù)庫
  15. .withClient("mobai").secret("123") // Client 賬號,、密碼。
  16. .authorizedGrantTypes("password","refresh_token") // 密碼模式 refresh_token 刷新token,,獲取token后會返回refresh_token回來用于token失效進行token刷新
  17. .scopes("user_info", "role_info") // 可授權的 Scope
  18. .refreshTokenValiditySeconds(1200); //刷新token 1200秒后失效
  19. }
  20. }

        除了上訴配置外,,其它操作跟密碼模式步驟一模一樣。  

啟動項目進行token獲?。?/p>

可以看見返回參數(shù)多了一個過期時間1200秒的刷新token,,refresh_token。

注意:經(jīng)測試,,客戶端模式和簡化模式不存在刷新token,。

        OAuth 2.0 中的客戶端模式(Client Credentials Grant)允許客戶端以自己的名義,而不是用戶的名義,,向授權服務器獲取訪問令牌,。在客戶端模式下,由于沒有用戶的概念,,因此通常不涉及到刷新令牌(Refresh Token)的發(fā)放,。

        OAuth 2.0 簡化授權(Implicit Grant)模式主要用于無服務器端的應用,如瀏覽器中的JavaScript應用,。在簡化模式中,,訪問令牌(Access Token)直接通過URL片段(hash fragment)返回給客戶端,由于安全原因以及協(xié)議設計,,Refresh Token通常不會在Implicit Grant流程中發(fā)放,。

2、通過刷新token獲取新token

        請求與獲取token及刷新token請求一樣,,只是參數(shù)不一樣,。

        grant_type參數(shù)值password換成了 refresh_token,并增加了刷新token參數(shù),。刷新token就是上面返回的刷新token,。

        可對比當前返回的token與小節(jié)1里面的token不一樣了,代表我們通過刷新token成功的獲取到了新的token,。

3,、項目整體結構

五,、刪除token

        新建delete_token_server服務,還是以密碼模式作為示例,,跟新建密碼模式服務步驟一模一樣,。只不過在密碼的基礎添加東西。

1,、新建刪除令牌token接口

  1. @RestController
  2. @RequestMapping("/oauth")
  3. public class DeleteTokenController {
  4. @Autowired
  5. private ConsumerTokenServices tokenServices;
  6. @PostMapping("/deleteToken")
  7. public String deleteToken(@RequestParam("token") String token) {
  8. tokenServices.revokeToken(token);
  9. return token + "token已刪除";
  10. }
  11. }

2,、資源服務器配置修改

        添加刪除token接口放行。

3,、啟動項目

        跟密碼模式一樣,。

4、獲取token

        跟密碼模式一樣,。

5、調用刪除token接口

        1.1 刪除token接口填寫獲取到的token值

        1.2 刪除token接口請求頭中填寫要刪除的token值

        1.3 結果

        刪除成功

再次訪問的話,,會報token無效,,說明token刪除成功。

6,、項目整體結構

注意,,實際生產環(huán)境下,授權服務器和資源服務器可能是不在一起的,,所以此處刪除控制器僅僅是示例,。

六、刪除刷新token

        新建delete_refresh_token服務,,還是以密碼模式作為示例,,跟新建密碼模式服務步驟一模一樣。只不過在密碼的基礎添加東西,。

1,、注入TokenStore

        創(chuàng)建配置類,注入需要用到刪除刷新token的bean

  1. import org.springframework.context.annotation.Bean;
  2. import org.springframework.context.annotation.Configuration;
  3. import org.springframework.security.oauth2.provider.token.TokenStore;
  4. import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
  5. @Configuration
  6. public class OAuth2Config {
  7. @Bean
  8. public TokenStore tokenStore() {
  9. return new InMemoryTokenStore(); // 或者使用JdbcTokenStore,、RedisTokenStore等其他實現(xiàn)
  10. }
  11. }

2,、新建刪除刷新token接口

  1. @RestController
  2. @RequestMapping("/oauth")
  3. public class DeleteTokenController {
  4. @Autowired
  5. private TokenStore tokenStore;
  6. @PostMapping("/deleteRefreshToken")
  7. public String deleteRefreshToken(@RequestParam("refreshToken") String refreshToken) {
  8. tokenStore.removeRefreshToken(new DefaultOAuth2RefreshToken(refreshToken));
  9. return refreshToken + " refreshToken已刪除";
  10. }
  11. }

2、資源服務器配置修改

        與刪除token中資源服務器配置修改一樣,。

3,、啟動項目

        與密碼模式一樣。

4,、獲取token及刷新token

        跟獲取刷新token小節(jié)(獲取token及刷新token)請求一樣

5,、調用刪除刷新token接口

        1.1 填入獲取到的token

        1.2 填入要刪除的刷新token

        1.3 結果

6、項目整體結構

    本站是提供個人知識管理的網(wǎng)絡存儲空間,,所有內容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,,謹防詐騙,。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報,。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多