优化平板信息获取,优化推送复用及增加用户推送
This commit is contained in:
@@ -1,31 +1,21 @@
|
||||
package com.onekeycall.videotablet.controller;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.onekeycall.videotablet.entity.DeviceInfo;
|
||||
import com.onekeycall.videotablet.entity.User;
|
||||
import com.onekeycall.videotablet.result.Result;
|
||||
import com.onekeycall.videotablet.service.DeviceSnService;
|
||||
import com.onekeycall.videotablet.service.UserService;
|
||||
import com.onekeycall.videotablet.utils.JwtUtil;
|
||||
import com.onekeycall.videotablet.utils.PushUtils;
|
||||
import com.onekeycall.videotablet.utils.DevicePushUtils;
|
||||
import com.onekeycall.videotablet.utils.TextUtils;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.JwtException;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.SignatureAlgorithm;
|
||||
import io.jsonwebtoken.security.Keys;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -82,11 +72,15 @@ public class BindSnController {
|
||||
return Result.error().message("sn already bind");
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
String verifyKey = RandomStringUtils.randomAlphanumeric(32);
|
||||
// PushUtils.aliyunAsyncPush(verifyKey, userPhone, sn);
|
||||
PushUtils.tpnsPush(verifyKey, userPhone, sn);
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("verify_key", verifyKey);
|
||||
params.addProperty("phone", userPhone);
|
||||
params.addProperty("expire_time", System.currentTimeMillis() + 60 * 1000);
|
||||
|
||||
// PushUtils.aliyunAsyncPush("1", params.toString(), sn);
|
||||
DevicePushUtils.tpnsPush("1", params.toString(), sn);
|
||||
redisTemplate.opsForValue().set(sn, verifyKey, 1, TimeUnit.MINUTES);
|
||||
return Result.ok().message("send message success");
|
||||
} catch (Exception e) {
|
||||
@@ -147,7 +141,7 @@ public class BindSnController {
|
||||
oldDeviceInfo.setToken(deviceToken);
|
||||
oldDeviceInfo.setSn(sn);
|
||||
deviceSnService.save(oldDeviceInfo);
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
map.put("phone", phone);
|
||||
map.put("device_token", deviceToken);
|
||||
map.put("device_sig", deviceSig);
|
||||
@@ -170,16 +164,32 @@ public class BindSnController {
|
||||
@RequestHeader("Device-Sig") String deviceSig,
|
||||
@RequestParam(value = "sn") String sn) {
|
||||
|
||||
if (!jwtUtil.validateDeviceToken(deviceToken, deviceId, sn)) {
|
||||
return Result.error().message("Invalid token");
|
||||
}
|
||||
|
||||
DeviceInfo deviceInfo = deviceSnService.findBySn(sn);
|
||||
if (deviceInfo == null) {
|
||||
return Result.notFound().message("sn not found");
|
||||
}
|
||||
|
||||
if (!deviceInfo.getBindSig().equals(deviceSig)) {
|
||||
return Result.error().message("device sig not match");
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(deviceInfo.getBindPhone())) {
|
||||
return Result.error().message("sn not bind");
|
||||
}
|
||||
|
||||
return Result.ok().message("sn bind");
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
map.put("bind_status", 1);
|
||||
map.put("device_alias", deviceInfo.getDeviceAlias());
|
||||
map.put("bind_phone", deviceInfo.getBindPhone());
|
||||
map.put("user_id", deviceInfo.getUserId());
|
||||
map.put("add_time", deviceInfo.getAddTime());
|
||||
map.put("bind_time", deviceInfo.getBindTime());
|
||||
|
||||
return Result.ok().data(map).message("sn bind");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,14 +1,7 @@
|
||||
package com.onekeycall.videotablet.controller;
|
||||
|
||||
import com.onekeycall.videotablet.entity.DeviceInfo;
|
||||
import com.onekeycall.videotablet.entity.User;
|
||||
import com.onekeycall.videotablet.result.Result;
|
||||
import com.onekeycall.videotablet.service.DeviceSnService;
|
||||
import com.onekeycall.videotablet.service.UserService;
|
||||
import com.onekeycall.videotablet.utils.JwtUtil;
|
||||
import com.onekeycall.videotablet.utils.PushUtils;
|
||||
import com.onekeycall.videotablet.utils.TextUtils;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
package com.onekeycall.videotablet.controller;
|
||||
|
||||
import com.onekeycall.videotablet.entity.DeviceInfo;
|
||||
import com.onekeycall.videotablet.entity.User;
|
||||
import com.onekeycall.videotablet.result.Result;
|
||||
import com.onekeycall.videotablet.service.DeviceSnService;
|
||||
import com.onekeycall.videotablet.service.UserService;
|
||||
import com.onekeycall.videotablet.utils.CXAESUtil;
|
||||
import com.onekeycall.videotablet.utils.JwtUtil;
|
||||
import com.onekeycall.videotablet.utils.PushUtils;
|
||||
import com.onekeycall.videotablet.utils.TextUtils;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
@@ -14,7 +14,6 @@ import com.tencent.xinge.bean.MessageAndroid;
|
||||
import com.tencent.xinge.bean.MessageType;
|
||||
import com.tencent.xinge.push.app.PushAppRequest;
|
||||
import darabonba.core.client.ClientOverrideConfiguration;
|
||||
import org.glassfish.jaxb.core.v2.TODO;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -23,10 +22,17 @@ import java.util.ArrayList;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class PushUtils {
|
||||
static Logger logger = LoggerFactory.getLogger(PushUtils.class);
|
||||
public class DevicePushUtils {
|
||||
static Logger logger = LoggerFactory.getLogger(DevicePushUtils.class);
|
||||
|
||||
public static void aliyunAsyncPush(String verifyKey, String phone, String sn) throws ExecutionException, InterruptedException {
|
||||
/**
|
||||
* @param title
|
||||
* @param jsonString
|
||||
* @param targetValue
|
||||
* @throws ExecutionException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public static void aliyunAsyncPush(String title, String jsonString, String targetValue) throws ExecutionException, InterruptedException {
|
||||
// HttpClient Configuration
|
||||
/*HttpClient httpClient = new ApacheAsyncHttpClientBuilder()
|
||||
.connectionTimeout(Duration.ofSeconds(10)) // Set the connection timeout time, the default is 10 seconds
|
||||
@@ -64,10 +70,6 @@ public class PushUtils {
|
||||
//.setConnectTimeout(Duration.ofSeconds(30))
|
||||
)
|
||||
.build();
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("verify_key", verifyKey);
|
||||
params.addProperty("phone", phone);
|
||||
params.addProperty("time", System.currentTimeMillis());
|
||||
|
||||
// Parameter settings for API request
|
||||
PushRequest pushRequest = PushRequest.builder()
|
||||
@@ -75,10 +77,10 @@ public class PushUtils {
|
||||
.pushType("MESSAGE")
|
||||
.deviceType("ANDROID")
|
||||
.target("ALIAS")
|
||||
.targetValue(sn)
|
||||
.title("1")
|
||||
.targetValue(targetValue)
|
||||
.title(title)
|
||||
.storeOffline(true)
|
||||
.body(params.toString())
|
||||
.body(jsonString)
|
||||
// Request-level configuration rewrite, can set Http request parameters, etc.
|
||||
// .requestConfiguration(RequestConfiguration.create().setHttpHeaders(new HttpHeaders()))
|
||||
.build();
|
||||
@@ -100,7 +102,7 @@ public class PushUtils {
|
||||
client.close();
|
||||
}
|
||||
|
||||
public static void tpnsPush(String verifyKey, String phone, String sn) {
|
||||
public static void tpnsPush(String title, String jsonString, String targetValue) {
|
||||
XingeApp xingeApp = new XingeApp.Builder()
|
||||
.appId("1500043720")
|
||||
.secretKey("1712af9e3079087447f4c35d2f622b89")
|
||||
@@ -116,22 +118,17 @@ public class PushUtils {
|
||||
//todo 为1时不能接收到不知什么原因 https://console.cloud.tencent.com/tpns/user-tools/1500043720/ap-guangzhou-1
|
||||
pushAppRequest.setAccount_push_type(0);
|
||||
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("verify_key", verifyKey);
|
||||
params.addProperty("phone", phone);
|
||||
params.addProperty("expire_time", System.currentTimeMillis() + 60 * 1000);
|
||||
|
||||
Message message = new Message();
|
||||
// 推送标题
|
||||
message.setTitle("1");
|
||||
message.setTitle(title);
|
||||
// 推送内容
|
||||
message.setContent(params.toString());
|
||||
message.setContent(jsonString);
|
||||
MessageAndroid messageAndroid = new MessageAndroid();
|
||||
message.setAndroid(messageAndroid);
|
||||
pushAppRequest.setMessage(message);
|
||||
ArrayList<String> accountList = new ArrayList<>();
|
||||
// 添加绑定账号
|
||||
accountList.add(sn);
|
||||
accountList.add(targetValue);
|
||||
// 设置账号列表
|
||||
pushAppRequest.setAccount_list(accountList);
|
||||
|
||||
@@ -188,6 +188,7 @@ public class JwtUtil {
|
||||
|
||||
/**
|
||||
* 生成设备签名(首次绑定)
|
||||
*
|
||||
* @param sn 设备序列号
|
||||
* @return 设备唯一签名
|
||||
*/
|
||||
@@ -202,7 +203,8 @@ public class JwtUtil {
|
||||
|
||||
/**
|
||||
* 生成设备令牌(联合SN+deviceId)
|
||||
* @param sn 设备序列号
|
||||
*
|
||||
* @param sn 设备序列号
|
||||
* @param deviceId 设备ID
|
||||
* @return JWT格式令牌
|
||||
*/
|
||||
@@ -217,11 +219,29 @@ public class JwtUtil {
|
||||
|
||||
/**
|
||||
* 验证设备令牌
|
||||
*
|
||||
* @param deviceToken 设备令牌
|
||||
* @return 验证结果
|
||||
*/
|
||||
|
||||
public Claims validateDeviceToken(String deviceToken) {
|
||||
public boolean validateDeviceToken(String deviceToken, String deviceId, String sn) {
|
||||
Claims claims = parseDeviceToken(deviceToken);
|
||||
//验证设备ID一致性
|
||||
String tokenDeviceId = claims.getSubject();
|
||||
if (!deviceId.equals(tokenDeviceId)) {
|
||||
throw new SecurityException("设备ID不匹配");
|
||||
}
|
||||
|
||||
//验证SN一致性
|
||||
String tokenSn = claims.get("sn", String.class);
|
||||
if (!sn.equals(tokenSn)) {
|
||||
throw new SecurityException("SN不匹配");
|
||||
}
|
||||
|
||||
return true; // 通过所有校验
|
||||
}
|
||||
|
||||
public Claims parseDeviceToken(String deviceToken) {
|
||||
try {
|
||||
return Jwts.parser()
|
||||
.verifyWith(Keys.hmacShaKeyFor(TABLET_SECRET.getBytes()))
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
package com.onekeycall.videotablet.utils;
|
||||
|
||||
import com.aliyun.auth.credentials.Credential;
|
||||
import com.aliyun.auth.credentials.provider.StaticCredentialProvider;
|
||||
import com.aliyun.sdk.service.push20160801.AsyncClient;
|
||||
import com.aliyun.sdk.service.push20160801.models.PushRequest;
|
||||
import com.aliyun.sdk.service.push20160801.models.PushResponse;
|
||||
import com.google.gson.Gson;
|
||||
import com.tencent.xinge.XingeApp;
|
||||
import com.tencent.xinge.bean.AudienceType;
|
||||
import com.tencent.xinge.bean.Message;
|
||||
import com.tencent.xinge.bean.MessageAndroid;
|
||||
import com.tencent.xinge.bean.MessageType;
|
||||
import com.tencent.xinge.push.app.PushAppRequest;
|
||||
import darabonba.core.client.ClientOverrideConfiguration;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class UserPushUtils {
|
||||
static Logger logger = LoggerFactory.getLogger(UserPushUtils.class);
|
||||
|
||||
/**
|
||||
* @param title
|
||||
* @param jsonString
|
||||
* @param targetValue
|
||||
* @throws ExecutionException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public static void aliyunAsyncPush(String title, String jsonString, String targetValue) throws ExecutionException, InterruptedException {
|
||||
// HttpClient Configuration
|
||||
/*HttpClient httpClient = new ApacheAsyncHttpClientBuilder()
|
||||
.connectionTimeout(Duration.ofSeconds(10)) // Set the connection timeout time, the default is 10 seconds
|
||||
.responseTimeout(Duration.ofSeconds(10)) // Set the response timeout time, the default is 20 seconds
|
||||
.maxConnections(128) // Set the connection pool size
|
||||
.maxIdleTimeOut(Duration.ofSeconds(50)) // Set the connection pool timeout, the default is 30 seconds
|
||||
// Configure the proxy
|
||||
.proxy(new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("<your-proxy-hostname>", 9001))
|
||||
.setCredentials("<your-proxy-username>", "<your-proxy-password>"))
|
||||
// If it is an https connection, you need to configure the certificate, or ignore the certificate(.ignoreSSL(true))
|
||||
.x509TrustManagers(new X509TrustManager[]{})
|
||||
.keyManagers(new KeyManager[]{})
|
||||
.ignoreSSL(false)
|
||||
.build();*/
|
||||
|
||||
// Configure Credentials authentication information, including ak, secret, token
|
||||
StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder()
|
||||
// Please ensure that the environment variables ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET are set.
|
||||
.accessKeyId("LTAI5tAffPd7YNsEbNfQSiwU")
|
||||
.accessKeySecret("6RzsuGceNOUD0WFpRfQRZ8eLXdHtFA")
|
||||
//.securityToken(System.getenv("ALIBABA_CLOUD_SECURITY_TOKEN")) // use STS token
|
||||
.build());
|
||||
|
||||
// Configure the Client
|
||||
AsyncClient client = AsyncClient.builder()
|
||||
.region("cn-chengdu") // Region ID
|
||||
//.httpClient(httpClient) // Use the configured HttpClient, otherwise use the default HttpClient (Apache HttpClient)
|
||||
.credentialsProvider(provider)
|
||||
//.serviceConfiguration(Configuration.create()) // Service-level configuration
|
||||
// Client-level configuration rewrite, can set Endpoint, Http request parameters, etc.
|
||||
.overrideConfiguration(
|
||||
ClientOverrideConfiguration.create()
|
||||
// Endpoint 请参考 https://api.aliyun.com/product/Push
|
||||
.setEndpointOverride("cloudpush.aliyuncs.com")
|
||||
//.setConnectTimeout(Duration.ofSeconds(30))
|
||||
)
|
||||
.build();
|
||||
|
||||
// Parameter settings for API request
|
||||
PushRequest pushRequest = PushRequest.builder()
|
||||
.appKey(335580260L)
|
||||
.pushType("MESSAGE")
|
||||
.deviceType("ANDROID")
|
||||
.target("ALIAS")
|
||||
.targetValue(targetValue)
|
||||
.title(title)
|
||||
.storeOffline(true)
|
||||
.body(jsonString)
|
||||
// Request-level configuration rewrite, can set Http request parameters, etc.
|
||||
// .requestConfiguration(RequestConfiguration.create().setHttpHeaders(new HttpHeaders()))
|
||||
.build();
|
||||
|
||||
// Asynchronously get the return value of the API request
|
||||
CompletableFuture<PushResponse> response = client.push(pushRequest);
|
||||
// Synchronously get the return value of the API request
|
||||
PushResponse resp = response.get();
|
||||
logger.info(new Gson().toJson(resp));
|
||||
// Asynchronous processing of return values
|
||||
/*response.thenAccept(resp -> {
|
||||
logger.info(new Gson().toJson(resp));
|
||||
}).exceptionally(throwable -> { // Handling exceptions
|
||||
logger.info(throwable.getMessage());
|
||||
return null;
|
||||
});*/
|
||||
|
||||
// Finally, close the client
|
||||
client.close();
|
||||
}
|
||||
|
||||
public static void tpnsPush(String title, String jsonString, String targetValue) {
|
||||
|
||||
|
||||
|
||||
XingeApp xingeApp = new XingeApp.Builder()
|
||||
.appId("1500043720")
|
||||
.secretKey("1712af9e3079087447f4c35d2f622b89")
|
||||
.domainUrl("https://api.tpns.tencent.com/")
|
||||
.build();
|
||||
|
||||
PushAppRequest pushAppRequest = new PushAppRequest();
|
||||
// 选择推送目标类型
|
||||
pushAppRequest.setAudience_type(AudienceType.account);
|
||||
// 消息类型:通知栏或透传消息
|
||||
pushAppRequest.setMessage_type(MessageType.message);
|
||||
// 选择推送的账号类型
|
||||
//todo 为1时不能接收到不知什么原因 https://console.cloud.tencent.com/tpns/user-tools/1500043720/ap-guangzhou-1
|
||||
pushAppRequest.setAccount_push_type(0);
|
||||
|
||||
Message message = new Message();
|
||||
// 推送标题
|
||||
message.setTitle(title);
|
||||
// 推送内容
|
||||
message.setContent(jsonString);
|
||||
MessageAndroid messageAndroid = new MessageAndroid();
|
||||
message.setAndroid(messageAndroid);
|
||||
pushAppRequest.setMessage(message);
|
||||
ArrayList<String> accountList = new ArrayList<>();
|
||||
// 添加绑定账号
|
||||
accountList.add(targetValue);
|
||||
// 设置账号列表
|
||||
pushAppRequest.setAccount_list(accountList);
|
||||
|
||||
JSONObject ret = xingeApp.pushApp(pushAppRequest);
|
||||
logger.info(ret.toString());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user