您的位置:首页 > 新闻 > 热点要闻 > 衢州建校电话_龙之向导的发展前景_永久免费客服系统有哪些软件_百度seo官方网站

衢州建校电话_龙之向导的发展前景_永久免费客服系统有哪些软件_百度seo官方网站

2024/10/13 19:06:20 来源:https://blog.csdn.net/weixin_39996520/article/details/142886631  浏览:    关键词:衢州建校电话_龙之向导的发展前景_永久免费客服系统有哪些软件_百度seo官方网站
衢州建校电话_龙之向导的发展前景_永久免费客服系统有哪些软件_百度seo官方网站

一、什么是JWT?

1.1 JWT的基本概念

JWT(JSON Web Token)是一种用于在各方之间传递JSON格式信息的紧凑、URL安全的令牌(Token)。JWT的主要作用是验证用户身份或权限。它由三部分组成:

  1. Header(头部):标识令牌的类型和加密算法。
  2. Payload(载荷):包含了实际的身份信息及其他数据。
  3. Signature(签名):使用头部和载荷生成的签名,用于验证数据完整性和来源的可靠性。

1.2 JWT的结构

JWT的结构由三部分组成,它们通过点号(.)进行分隔,格式如下:

Header.Payload.Signature

具体每一部分的内容如下:

  • Header(头部): 通常包含两部分信息:令牌的类型(JWT)和签名的算法(如HMAC SHA256或RSA)。

    {"alg": "HS256","typ": "JWT"
    }
    
  • Payload(载荷): 载荷是JWT的主体部分,包含了需要传输的数据。通常包含以下几种常见的声明(Claims):

    • iss:签发者
    • exp:过期时间
    • sub:主题
    • aud:接收者
    • iat:签发时间
    • nbf:在此之前不可用
    {"sub": "1234567890","name": "John Doe","admin": true
    }
    
  • Signature(签名): 签名部分是用来验证消息的完整性,并确保其未被篡改。签名的生成方式如下:

    HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload),secret)
    

二、JWT的原理和机制

2.1 JWT的工作机制

JWT是无状态的令牌,每次客户端(如浏览器)与服务器进行交互时,客户端会在请求头中携带这个令牌,服务器根据JWT中的签名验证令牌的合法性,并通过载荷(Payload)中的信息进行身份确认。

JWT认证的基本流程

  1. 用户登录:用户提交用户名和密码。
  2. 服务器验证用户:服务器验证用户名和密码是否正确。
  3. 生成JWT:验证成功后,服务器根据用户信息生成一个JWT并返回给客户端。
  4. 客户端保存JWT:客户端通常会将JWT存储在本地存储(LocalStorage)或Cookies中。
  5. 请求携带JWT:每次客户端向服务器发送请求时,会在请求头中附加JWT。
  6. 服务器验证JWT:服务器通过解析JWT,确认用户身份及权限,进而决定是否响应请求。

2.2 为什么使用JWT?

在一个复杂的分布式系统中,例如电商交易系统,多个微服务之间需要频繁通信。传统的基于会话的认证方式存在以下缺点:

  • 状态依赖:服务器需要存储每个用户的会话信息,随着用户数量的增加,服务器的存储负担增加。
  • 扩展性差:在分布式环境中,多个服务器需要共享会话状态,这增加了系统复杂性。

相比之下,JWT是一种无状态的认证机制,不需要服务器存储会话信息。JWT本身携带了用户的认证信息,具有如下优点:

  • 扩展性强:无状态特性使得JWT在分布式架构下具有良好的扩展性。
  • 跨平台、跨语言支持:JWT是JSON格式的令牌,几乎可以被所有语言和平台解析使用。
  • 灵活性:JWT的Payload部分可以自定义数据,从而支持复杂的权限系统。

2.3 JwtUtils.extractClaims实现

JwtUtils.extractClaims是一个工具方法,用于解析JWT并提取其中的声明(claims),如用户ID、角色信息和过期时间。下面是一个典型的实现,它展示了如何验证JWT的有效性、检查签名,以及处理异常。

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureException;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.UnsupportedJwtException;import java.security.Key;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;public class JwtUtils {// 用于签名验证的密钥(示例使用HMAC)private static final String SECRET_KEY = "your-256-bit-secret";// 解码并生成用于验证的密钥对象private static Key getSigningKey() {byte[] keyBytes = Base64.getDecoder().decode(SECRET_KEY);return new SecretKeySpec(keyBytes, "HmacSHA256");}// 解析JWT并提取Claimspublic static Claims extractClaims(String token) {try {return Jwts.parserBuilder().setSigningKey(getSigningKey()) // 设置密钥用于签名验证.build().parseClaimsJws(token) // 解析并验证JWT.getBody(); // 返回Payload部分的Claims} catch (ExpiredJwtException e) {System.err.println("JWT已过期: " + e.getMessage());throw e;} catch (UnsupportedJwtException | MalformedJwtException e) {System.err.println("无效的JWT: " + e.getMessage());throw new IllegalArgumentException("Invalid JWT");} catch (SignatureException e) {System.err.println("JWT签名不匹配: " + e.getMessage());throw new SecurityException("Invalid signature");} catch (IllegalArgumentException e) {System.err.println("JWT为空或格式不正确: " + e.getMessage());throw e;}}
}

解析说明:

  1. 密钥管理getSigningKey()方法用于将Base64编码的字符串转换为签名密钥。
  2. 异常处理:解析JWT时可能出现多种异常,例如JWT过期签名无效格式错误等。通过捕获这些异常,我们可以进行相应的错误处理。
  3. 验证Token的有效性parseClaimsJws()会自动验证签名和Token格式,确保JWT未被篡改。

2.4 JwtUtils.extractClaims 所需的 Maven 依赖

为了实现 JwtUtils.extractClaims 方法,需要使用一个专门处理 JWT 的库。在之前的实现中,我们使用了 JJWT (Java JWT) 库。以下是 JJWT 所需的 Maven 依赖配置。

<!-- pom.xml -->
<dependencies><!-- JJWT: JSON Web Token for Java and Android --><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><version>0.11.5</version></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-impl</artifactId><version>0.11.5</version><scope>runtime</scope></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-jackson</artifactId> <!-- or jjwt-gson if you prefer --><version>0.11.5</version><scope>runtime</scope></dependency><!-- 其他依赖项 --><!-- ... -->
</dependencies>

依赖说明:

  1. jjwt-api:提供 JWT 的核心接口和类。
  2. jjwt-impl:包含 jjwt 的实现部分,必须与 jjwt-api 一起使用。
  3. jjwt-jackson:用于 JSON 处理,支持使用 Jackson 库进行序列化和反序列化。如果您更喜欢使用 Gson,可以替换为 jjwt-gson

注意事项:

  • 确保所有 jjwt 依赖的版本一致,以避免兼容性问题。
  • 如果您使用的是 Spring Boot,可以考虑使用 Spring Security 提供的 JWT 支持,以简化集成过程。

三、JWT在电商交易系统中的应用

3.1 电商系统中的角色与权限

在电商交易系统中,涉及多个角色,例如:

  • 普通用户:可以浏览商品、下订单、查看订单状态。
  • 商家用户:可以管理商品、处理订单。
  • 管理员:可以管理平台用户、审核商家、处理投诉等。

系统需要根据不同用户的角色赋予相应的权限,而JWT可以通过其载荷中的角色信息实现权限管理。

3.2 电商系统的JWT认证流程

我们以一个电商交易系统为例,说明JWT在用户身份验证、订单管理中的应用。系统架构主要分为以下几个模块:

  1. 用户服务:负责用户的注册、登录、生成JWT令牌。
  2. 商品服务:提供商品的查询、展示等功能。
  3. 订单服务:处理订单的生成、状态管理。
  4. 支付服务:处理用户支付。
3.2.1 用户登录与JWT生成

用户登录时,系统会验证用户的用户名和密码,验证通过后生成JWT令牌并返回给客户端。这个令牌包含了用户的身份信息和角色权限。

登录流程的时序图:

在这里插入图片描述

3.2.2 请求保护资源

用户登录后,可以浏览商品或下订单。在每次请求时,客户端会在请求头中携带JWT令牌,服务器通过验证JWT来确认用户身份。

请求订单详情时的时序图:

在这里插入图片描述

3.3 电商系统中的JWT权限控制

在电商系统中,不同角色的用户具备不同的权限,JWT的Payload中可以存储用户的角色信息(如role),系统在处理请求时,根据JWT中的角色信息进行权限验证。

3.3.1 权限检查

例如:

  • 普通用户只能查看自己的订单;
  • 商家用户可以查看商家店铺的订单;
  • 管理员可以查看所有订单。

订单服务中的权限检查流程:

@RestController
@RequestMapping("/orders")
public class OrderController {@GetMapping("/{orderId}")public ResponseEntity<?> getOrder(@RequestHeader("Authorization") String token, @PathVariable Long orderId) {Claims claims = JwtUtils.extractClaims(token.replace("Bearer ", ""));String role = claims.get("role", String.class);Long userId = claims.get("userId", Long.class);Order order = orderService.findOrderById(orderId);if (order == null) {return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Order not found");}// 权限检查if ("USER".equals(role) && !order.getUserId().equals(userId)) {return ResponseEntity.status(HttpStatus.FORBIDDEN).body("You don't have permission to access this order");}return ResponseEntity.ok(order);}
}

在这个示例中,OrderController首先从JWT中提取用户角色和用户ID,然后根据不同角色的权限规则决定是否返回订单详情。

四、前端与后端的JWT交互示例

在电商系统中,前端通常通过JavaScript与后端进行交互。以下我们提供一个简单的HTML和JavaScript示例,展示如何通过JWT进行用户登录、访问受保护的资源。

4.1 登录功能

当用户提交用户名和密码时,前端会将这些数据发送给后端,后端验证成功后返回JWT,前端将其存储在localStorage中,用于后续的API请求。

HTML和JavaScript代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>JWT Login</title>
</head>
<body><h1>JWT Login Example</h1><form id="loginForm"><label for="username">Username:</label><input type="text" id="username" required><br><label for="password">Password:</label><input type="password" id="password" required><br><button type="submit">Login</button></form><div id="orderDetails" style="display:none;"><h2>Order Details</h2><pre id="orderContent"></pre></div><script>document.getElementById('loginForm').addEventListener('submit', function (event) {event.preventDefault();const username = document.getElementById('username').value;const password = document.getElementById('password').value;// 发送登录请求fetch('http://localhost:8080/api/login', {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify({ username, password })}).then(response => response.json()).then(data => {// 存储JWT到localStoragelocalStorage.setItem('jwt', data.token);alert('Login successful');}).catch(error => console.error('Error:', error));});// 请求受保护的资源function fetchOrderDetails(orderId) {const token = localStorage.getItem('jwt');if (!token) {alert('Please login first');return;}fetch(`http://localhost:8080/api/orders/${orderId}`, {method: 'GET',headers: {'Authorization': `Bearer ${token}`}}).then(response => response.json()).then(order => {document.getElementById('orderContent').textContent = JSON.stringify(order, null, 2);document.getElementById('orderDetails').style.display = 'block';}).catch(error => console.error('Error:', error));}// 示例调用fetchOrderDetails(12345);</script>
</body>
</html>

4.2 前端代码说明

  • 用户登录时,前端通过fetch API向后端发送POST请求,后端验证成功后返回JWT,前端将其存储在localStorage中。
  • 在请求订单详情时,前端会将JWT添加到请求头中发送给后端,后端验证JWT的合法性后返回订单数据。

五、常见问题与解决方案

5.1 JWT过期问题的细化解决方案

问题:JWT一旦达到exp设定的过期时间,就会被视为无效,用户需要重新登录。这在用户体验上可能造成困扰,特别是当会话中断时。

解决方案一:刷新Token机制(Refresh Token)

Refresh Token是一种辅助机制,用于延长会话时长。具体步骤如下:

  1. 初次登录:服务器返回一个短时效的JWT和一个长期有效的Refresh Token。

  2. Token过期检查:在客户端请求时,如果JWT已过期,则使用Refresh Token获取新的JWT。

  3. 刷新JWT:

    • 客户端向服务器发送Refresh Token。
    • 服务器验证Refresh Token的合法性,若有效则生成新的JWT并返回。
    • 将新的JWT存储到客户端,并继续操作。

示例代码:刷新Token的实现

@PostMapping("/api/refresh-token")
public ResponseEntity<?> refreshToken(@RequestBody String refreshToken) {try {Claims claims = JwtUtils.extractClaims(refreshToken);if (claims != null) {// 验证通过,生成新的JWTString newJwt = JwtUtils.generateToken(claims.getSubject(), 15); // 新的JWT有效期15分钟return ResponseEntity.ok(Map.of("token", newJwt));}} catch (ExpiredJwtException e) {return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Refresh Token expired");}return ResponseEntity.status(HttpStatus.FORBIDDEN).body("Invalid Refresh Token");
}

注意:Refresh Token应该比JWT更长效,但同样需要妥善保护,避免泄露。


解决方案二:短时效与长会话相结合

思路:通过设置短时效JWT并动态刷新,确保在用户活动期间会话不会中断。

流程

  1. JWT过期时间设置为10~15分钟
  2. 每次用户操作时,通过客户端检测JWT的剩余有效期:
    • 如果剩余有效期不足5分钟,则向服务器请求新的Token。
  3. 用户不活动时,不自动刷新JWT。这样可以限制Token滥用的风险。

示例:检测并自动刷新Token的JavaScript代码

function isTokenExpiringSoon(token) {const payload = JSON.parse(atob(token.split('.')[1]));const expTime = payload.exp * 1000; // 转换为毫秒const currentTime = Date.now();return (expTime - currentTime) < 5 * 60 * 1000; // 剩余不足5分钟
}function refreshTokenIfNeeded() {const token = localStorage.getItem('jwt');if (token && isTokenExpiringSoon(token)) {fetch('http://localhost:8080/api/refresh-token', {method: 'POST',headers: { 'Content-Type': 'application/json' },body: JSON.stringify(token)}).then(response => response.json()).then(data => localStorage.setItem('jwt', data.token)).catch(err => console.error('Token刷新失败:', err));}
}// 页面加载或用户操作时调用
document.addEventListener('click', refreshTokenIfNeeded);

5.2 JWT的大小问题

问题: JWT包含较多信息(如用户ID、角色、权限等),且使用Base64编码后体积较大,增加了网络带宽消耗。

解决方案:

  1. 精简 Payload:减少JWT中存储的数据,只存储必要的用户身份信息。
  2. 压缩 Token:可以通过GZIP等方式对JWT进行压缩后再进行传输。
5.2.1 精简 Payload

策略:

  • 仅存储必要信息:确保JWT的Payload中只包含验证用户身份所需的最少信息。例如,用户ID、用户名和角色可能是必要的,而不需要包含用户的详细资料。
  • 使用简短的声明名称:采用简短的键名来减少总体大小。例如,使用uid代替userIdr代替role

示例:

{"uid": "1234567890","n": "John Doe","r": "ADMIN"
}

实现示例:

public class JwtUtils {// 生成精简的JWTpublic static String generateToken(String userId, String username, String role, long expirationMinutes) {Claims claims = Jwts.claims().setSubject(userId);claims.put("n", username); // 简短的键名claims.put("r", role);     // 简短的键名return Jwts.builder().setClaims(claims).setIssuedAt(new Date()).setExpiration(new Date(System.currentTimeMillis() + expirationMinutes * 60 * 1000)).signWith(getSigningKey(), SignatureAlgorithm.HS256).compact();}
}

优点:

  • 减少 Token 大小:通过减少Payload中的数据量,显著降低JWT的总体大小。
  • 提升性能:较小的Token减少了网络传输的带宽消耗,提升请求的响应速度。

注意事项:

  • 平衡信息量与安全性:确保仅删除不必要的信息,避免影响系统的功能和安全性。
  • 一致性:在前后端以及各个微服务中统一Payload的结构和字段名称,避免解析错误。
5.2.2 压缩 Token

策略:

  • 使用压缩算法:在生成JWT后,使用GZIP等压缩算法对其进行压缩,然后进行Base64编码传输。
  • 服务器端解压:接收端需要在解析JWT前先进行解压缩。

实现示例:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.zip.GZIPOutputStream;
import java.util.zip.GZIPInputStream;public class JwtUtils {// 压缩JWTpublic static String compressToken(String token) throws IOException {ByteArrayOutputStream byteStream = new ByteArrayOutputStream(token.length());try (GZIPOutputStream gzip = new GZIPOutputStream(byteStream)) {gzip.write(token.getBytes());}return Base64.getEncoder().encodeToString(byteStream.toByteArray());}// 解压JWTpublic static String decompressToken(String compressedToken) throws IOException {byte[] compressedBytes = Base64.getDecoder().decode(compressedToken);ByteArrayInputStream byteStream = new ByteArrayInputStream(compressedBytes);ByteArrayOutputStream out = new ByteArrayOutputStream();try (GZIPInputStream gzip = new GZIPInputStream(byteStream)) {byte[] buffer = new byte[256];int n;while ((n = gzip.read(buffer)) >= 0) {out.write(buffer, 0, n);}}return out.toString();}
}

前端与后端的集成:

  • 生成压缩Token:

    String token = JwtUtils.generateToken(userId, username, role, 15);
    String compressedToken = JwtUtils.compressToken(token);
    // 将compressedToken发送给客户端
    
  • 客户端存储与传输:

    客户端接收并存储压缩后的Token。每次发送请求时,发送压缩Token。

  • 服务器端接收与解压:

    @GetMapping("/api/orders/{orderId}")
    public ResponseEntity<?> getOrder(@RequestHeader("Authorization") String compressedToken, @PathVariable Long orderId) {try {String token = JwtUtils.decompressToken(compressedToken.replace("Bearer ", ""));Claims claims = JwtUtils.extractClaims(token);// 继续处理请求} catch (IOException e) {return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Invalid Token");}// ...
    }
    

优点:

  • 显著减小Token体积:尤其是在Payload包含较多数据时,压缩效果显著。
  • 透明性:对前后端系统的改动较小,只需在传输环节增加压缩与解压步骤。

缺点:

  • 增加处理开销:压缩与解压缩会增加一定的CPU资源消耗,可能影响性能。
  • 复杂性:需要在前后端系统中增加相应的压缩与解压缩逻辑,增加系统复杂性。

注意事项:

  • 选择合适的压缩算法:GZIP是常用的选择,但也可以根据具体需求选择其他压缩算法。
  • 确保一致性:前后端必须严格按照相同的压缩与解压缩流程进行操作,避免Token解析失败。
5.2.3 其他优化策略

除了精简Payload和压缩Token外,还可以考虑以下优化策略:

  1. 使用短期Token与会话机制
    • 概述:结合使用短期有效的JWT和基于会话的状态管理。
    • 实现:JWT用于身份验证,短期内有效,结合服务器端的会话存储,用于管理用户的会话状态。
  2. 分片存储
    • 概述:将部分数据存储在客户端(如LocalStorage),将敏感数据存储在服务器端。
    • 实现:JWT只包含必要的身份信息,其他详细数据通过API查询获取。
  3. 自定义编码
    • 概述:使用自定义的编码方式替代标准的Base64,以减少字符数。
    • 实现:例如使用Base62编码替代Base64,减少Token长度。

选择适合的优化策略需要根据具体的系统需求和约束条件进行权衡。


5.3 JWT的安全性问题

问题: 虽然JWT签名可以保证数据不被篡改,但JWT的Payload部分是明文的,攻击者可以解码其中的敏感信息。

解决方案:

  1. 加密JWT:使用JWE(JSON Web Encryption)标准对JWT进行加密,确保敏感信息的安全性。
  2. 使用 HTTPS:始终通过HTTPS协议传输JWT,避免在网络传输中被拦截。
5.3.1 加密JWT

概述:

  • JWE (JSON Web Encryption) 是一种标准,用于对JWT的内容进行加密,确保数据的机密性。
  • 与JWS(JSON Web Signature)不同,JWE不仅可以验证数据的完整性和来源,还能保护数据不被未经授权的第三方读取。

实现示例:

import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import javax.crypto.SecretKey;
import java.util.Base64;
import java.util.Date;public class JwtUtils {// 生成加密密钥(示例使用AES)private static final String SECRET_KEY = "your-256-bit-secret-your-256-bit-secret"; // 32字节密钥private static final SecretKey KEY = Keys.hmacShaKeyFor(SECRET_KEY.getBytes());// 生成加密JWTpublic static String generateEncryptedToken(String userId, String username, String role, long expirationMinutes) {return Jwts.builder().setSubject(userId).claim("n", username).claim("r", role).setIssuedAt(new Date()).setExpiration(new Date(System.currentTimeMillis() + expirationMinutes * 60 * 1000)).signWith(KEY, SignatureAlgorithm.HS256).compressWith(CompressionCodecs.GZIP) // 可选:压缩Payload.encryptWith(Keys.secretKeyFor(SignatureAlgorithm.HS256)) // 使用对称密钥加密.compact();}// 解密JWTpublic static Claims extractEncryptedClaims(String encryptedToken) {try {return Jwts.parserBuilder().setSigningKey(KEY).build().parseClaimsJws(encryptedToken).getBody();} catch (JwtException e) {// 处理异常throw new SecurityException("Invalid encrypted JWT");}}
}

注意事项:

  • 密钥管理:加密密钥必须妥善保管,避免泄露。建议使用环境变量或专用的密钥管理服务(如 AWS KMS、Azure Key Vault)。
  • 性能开销:加密与解密会带来额外的计算开销,需评估对系统性能的影响。
  • 兼容性:确保前后端系统支持JWE标准,或使用相同的加密机制。
5.3.2 使用 HTTPS

概述:

  • HTTPS (HTTP Secure) 是在HTTP基础上加入SSL/TLS协议,确保数据在传输过程中被加密,防止被窃听或篡改。
  • 在传输JWT时,使用HTTPS可以防止Token被中间人攻击者截获和利用。

实现步骤:

  1. 获取 SSL/TLS 证书
  • 可以通过证书颁发机构(如 Let’s Encrypt)获取免费的SSL/TLS证书。
  1. 配置服务器
  • 在后端服务器(如 Nginx、Apache、Tomcat)上配置SSL/TLS,确保所有API请求通过HTTPS进行。

  • 示例(Nginx)

    server {listen 443 ssl;server_name yourdomain.com;ssl_certificate /path/to/fullchain.pem;ssl_certificate_key /path/to/privkey.pem;ssl_protocols TLSv1.2 TLSv1.3;ssl_ciphers HIGH:!aNULL:!MD5;location /api/ {proxy_pass http://localhost:8080/api/;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;}
    }
    
  1. 强制 HTTPS
  • 确保所有HTTP请求重定向到HTTPS,避免用户通过不安全的连接访问系统。

  • 示例(Nginx)

    server {listen 80;server_name yourdomain.com;return 301 https://$host$request_uri;
    }
    
  1. 前端配置
  • 确保前端应用通过HTTPS协议与后端进行通信,避免混合内容问题。

优点:

  • 数据加密:确保JWT在传输过程中不被窃听或篡改。
  • 数据完整性:防止数据在传输过程中被修改。

注意事项:

  • 证书管理:定期更新SSL/TLS证书,避免证书过期导致服务中断。
  • 性能优化:使用HTTP/2等协议优化HTTPS连接的性能。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com