For more information about the code, see Server-Side Demo.
sdf-starter current version : 1.3.0-developer-SNAPSHOT
<dependency><groupId>com.tuya</groupId><artifactId>sdf-developer-starter</artifactId><version>${sdf.version}</version></dependency><repositories><repository><id>tuya-maven</id><url>https://maven-other.tuya.com/repository/maven-public/</url></repository></repositories>
In Application.java
, add the package sdf-starter
to the scan directory. Add the required interceptor to the request interceptor.
TIP
When you add scanBasePackages
, make sure to add com.tuya.sdf.starter
and the package path of your applications.
package com.tuya.isv.demo;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication(scanBasePackages = {"com.tuya.sdf.starter","com.tuya.isv.demo"})public class IsvDemoApplication {public static void main(String[] args) {SpringApplication.run(IsvDemoApplication.class, args);}}
Copy the App Key
and Secret Key
from the SaaS No-Code Platform.
Log in to the SaaS No-Code Platform.
Choose My Applications. Click View Development Credentials.
Copy the credentials for use.
# application.propertiesdeveloper.code=hdxxxxxxxxxxxxydeveloper.key=iuIg9oxxxxxxxxxxxxxxxxei
@RestControllerpublic class DeviceController {// Inject Bean for cloud-to-cloud integration.@ResourceDeviceAbility deviceAbility;@GetMapping("/hello")public JSONObject hello() {// Get information about the user of the current request.SdfUser user = SdfContextHolder.getUser();// Get information about the SaaS of the current request.SdfSaas sdfSaas = SdfContextHolder.getSdfSaas();System.out.println(JSON.toJSONString(user));System.out.println(JSON.toJSONString(sdfSaas));// Call the cloud APIs using the cloud-to-cloud integration SDK to get the instruction set by product category.JSONObject result = deviceAbility.queryDeviceFunctions("dj");return result;}}
public interface DeviceAbility {@GET("/v1.0/functions/{category}")JSONObject queryDeviceFunctions(@Path("category") String category);}
x-sdf-auth
is the JWT parameter. For more information, see JWT Features.
Generate a JWT and start testing.
The interceptor path: com.tuya.sdf.starter.interceptor.SdfContextInterceptor
.
Hot to implement the interceptor:
developer.code
and developer.key
to decode JWT. Get and set the SaaS and user information of the current request.tuya-connector
.@Slf4j@Componentpublic class SdfContextInterceptor implements HandlerInterceptor {private static final String JWT_HEADER = "x-sdf-auth";private static final ObjectMapper objectMapper = new ObjectMapper();@Resourceprivate Configuration configuration;@Value("${developer.code:#{null}}")private String developerCode;@Value("${developer.key:#{null}}")private String developerKey;private SdfCrypt sdfCrypt;@PostConstructpublic void init() {sdfCrypt = new SdfCrypt(developerCode, developerKey);}@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {try {String header = request.getHeader(JWT_HEADER);if (StringUtils.isBlank(header)) {log.warn("header:[" + JWT_HEADER + "] is null");return true;}Jws<Claims> jws = Jwts.parserBuilder().setSigningKey(Encoders.BASE64URL.encode(developerKey.getBytes(StandardCharsets.UTF_8))).build().parseClaimsJws(header);Object userObj = jws.getBody().get("user");Object saasObj = jws.getBody().get("saas");if (Objects.isNull(userObj) || Objects.isNull(saasObj)) {log.error("header token user and saas can't null");throw new SdfException(HEADER_TOKEN_ERROR);}String userStr = objectMapper.writeValueAsString(userObj);SdfUser sdfUser = objectMapper.readValue(userStr, SdfUser.class);SdfContextHolder.setUser(sdfUser);String saasStr = objectMapper.writeValueAsString(saasObj);SdfContextHolder.setSdfSaas(objectMapper.readValue(saasStr, SdfSaas.class));String clientId = sdfCrypt.decrypt(SdfContextHolder.getSdfSaas().getClientId());String secretKey = sdfCrypt.decrypt(SdfContextHolder.getSdfSaas().getSecretKey());configuration.getApiDataSource().setAk(clientId);configuration.getApiDataSource().setSk(secretKey);} catch (SignatureException e) {log.error("header jwt signature error", e);throw new SdfException(HEADER_TOKEN_ERROR);} catch (Exception e) {log.error("jwt parser error", e);throw new SdfException(HEADER_TOKEN_ERROR);}return true;}}
Call the method SdfDeveloperUtil.generateJwtHeader()
to generate JSON Web Token (JWT) for backend API debugging.
@SpringBootTest@TestPropertySource("classpath:application.properties")class IsvDemoApplicationTests {@Testvoid contextLoads() {}@Value("${developer.code}")private String developerCode;@Value("${developer.key}")private String developerKey;@Testvoid jwtTest() {// Set user objects.SdfUser sdfUser = new SdfUser();sdfUser.setUserId("bayxxxxxxxxxxxxrh");// Set SaaS objects.SdfSaas sdfSaas = new SdfSaas();sdfSaas.setClientId("upxxxxxxxxxxxxxxxfma");sdfSaas.setSecretKey("a5xxxxxxxxxxxxxxxxxxb7");String u = JSON.toJSONString(sdfUser);String s = JSON.toJSONString(sdfSaas);System.out.println(u);System.out.println(s);// Generate JWT.System.out.println(SdfDeveloperUtil.generateJwtHeader(developerCode, developerKey, sdfUser, sdfSaas));}}