DeveloperDeveloper
  • Standard Solutions
  • Cam Solutions
  • Native SDKs
  • App Gallery
  • Game Engine Plugins
Forum
Projects Library
Dev Discord
  • Standard Solutions
  • Cam Solutions
  • Native SDKs
  • App Gallery
  • Game Engine Plugins
Forum
Projects Library
Dev Discord
  • App Gallery (with Lovense Remote)
    • Get Started
    • Development
    • Deploy
  • Basic API
    • Life Cycle
  • Platform API
    • App Info
      • AppBaseInfo
    • Toy
      • Toy Info
      • Command
      • Feedback Mode
    • Device
      • Accelerometer
      • Screen Orientation
      • Shake
      • Vibrate
    • File System
      • Save Image
  • Open API
    • User Authorization
      • Client API
      • Server API
  • Error Code
  • Get authCode
  • Use appSecret to encrypt authCode into sign
  • Get Access Token and User ID using authCode
  • Server API
    • Get Access Token HTTP API
    • Get User Info HTTP API
Got Stuck?
Forum for Lovense Developers
Support
Document Feedback

Server API

Get authCode

The developer can use userManager.getAuthCode to get authCode.

When calling it

  • scope is a core parameter that affects accessToken's ability to access resources.
  • authCode is valid for a single use and will expire after that. Repeated use of authCode triggers alerts.
  • authCode will expire in 3 minutes, so please get the accessToken and userId using authCode as soon as possible.

Use appSecret to encrypt authCode into sign

How to encrypt:

  • The developer uses App Secret as the key to encrypt the authCode to produce a sign. Go to App Gallery Console to get the App Secret.
  • The encryption method, signType, can only use HmacSHA256 at this time.
  • The encrypted string should be Base64 encoded.

Lovense Remote server will compare the decrypted sign to authCode, and access will be denied if the comparison fails.

Java Code Example

import sun.misc.BASE64Encoder;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;

public String useSecretGenerateSign(String authCode, String appSecret) throws Exception {
    Mac sha256HMAC = Mac.getInstance("HmacSHA256");
    SecretKeySpec secretKey = new SecretKeySpec(appSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
    sha256HMAC.init(secretKey);
    byte[] bytes = sha256HMAC.doFinal(authCode.getBytes(StandardCharsets.UTF_8));
    return (new BASE64Encoder()).encodeBuffer(bytes);
}

Get Access Token and User ID using authCode

The developer can use Get Access Token HTTP API and Get User Info HTTP API to get accessToken and userId.

Calling the interface with authCode to get an accessToken also returns a refreshToken, which can be used to refresh a new accessToken within the refreshToken's validity period.

The accessToken is used to access the lovense APIs, which determine the scope of the accessToken's privileges and only allow access to interfaces within that scope.

Java Code Example

URI uri  = new URIBuilder().setScheme("https").setHost("appgallery.lovense.com").setPath("/remote-dev-api/oauth").build();

HttpPost post = new HttpPost(uri);
post.setHeader("Content-Type", "application/json;charset=utf8");
post.setHeader("developerToken", developerToken);

// user HttpClient
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
CloseableHttpResponse response = httpClient.execute(post);
// gets the response entity from the response model
HttpEntity responseEntity = response.getEntity();

// assemble request body
String appId = "your appId";
String appSecret = "your appSecret";
String grantType = "authorizationCode"; // or refreshToken

Param param = new Param();
param.setAppId(appId);
param.setGrantType(grantType);
if (Objects.equals("refreshToken", param.getGrantType())) {
    String refreshToken = "Persist refreshToken in your server";
    param.setFreshToken(refreshToken);
} else if (Objects.equals("authorizationCode", param.getGrantType())) {
    String authCode = "authCode obtained from the sdk";
    String sign = this.useSecretGenerateSign(param.getAuthCode(), appSecret);
    param.setAuthCode(authCode);
    param.setSign(sign);
    param.setSignType("HmacSHA256"); // Currently, only HmacSHA256 is accepted

}
StringEntity entity = new StringEntity(JsonUtil.toJson(param), "UTF-8");
post.setEntity(entity);

// send request
String contentStr = EntityUtils.toString(responseEntity);

DataResponse content = JsonUtil.toBean(contentStr, DataResponse.class);
OAuthResponseData data = JsonUtil.toBean(JsonUtil.toJson(content.getData()), OAuthResponseData.class);

class AccessUserInfo {

    private boolean result;

    private int code;

    private Strig message;

    private Object data;

  // omit getter and setter methods
}

class OAuthResponseData {

    private String accessToken;

    private Long expiresIn;

    private String refreshToken;

    private Long reExpiresIn;

    private String userId;

  // omit getter and setter methods
}

Get userInfo using accessToken

The developer can use this interface to get userInfo:

GetUserInfo Request

Java Code Example

// obtain user information using accessToken
URI uri  = new URIBuilder().setScheme("https").setHost("appgallery.lovense.com").setPath("/remote-dev-api/user/info").build();

HttpPost post = new HttpPost(uri);
post.setHeader("Content-Type", "application/json;charset=utf8");
post.setHeader("developerToken", developerToken); // your developerToken
post.setHeader("accessToken", accessToken); // accessToken from step2

// user HttpClient
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
CloseableHttpResponse response = httpClient.execute(post);
// gets the response entity from the response model
HttpEntity responseEntity = response.getEntity();
String contentStr = EntityUtils.toString(responseEntity);

DataResponse content = JsonUtil.toBean(contentStr, DataResponse.class);
AccessUserInfo data = JsonUtil.toBean(JsonUtil.toJson(content.getData()), AccessUserInfo.class);

class AccessUserInfo {

    private boolean result;

    private int code;

    private Strig message;

    private Object data;

  // omit getter and setter methods
}

class AccessUserInfo {

    private String name;

  // omit getter and setter methods
}

Server API

Get Access Token HTTP API

API URL: https://appgallery.lovense.com/remote-dev-api/oauth

Method: POST

Content Type:  application/json

Headers:

NameDescriptionTypeRequired
developerTokenDeveloper tokenstringyes

Parameters:

NameDescriptionTypeNoteRequired
appIdAppcation IDstringGet Appcation ID from App Gallery Consoleyes
grantTypeDecide whether to get authCode or refreshTokenstringauthorizationCode: used when exchanging authCode for accessToken. refreshToken: used when exchanging refreshToken for accessTokenyes
authCodeThe authCode obtained in the first stepstringRequired if grantType=authorizationCodeno
signSign of authCode. It is used to verify that the authcode is legal.stringRequired if grantType=authorizationCode and use appSecret as encryption keyno
signTypeEncryption methodstringRequired if grantType=authorizationCode and HmacSHA256 only for now.no
refreshTokenThe refreshToken obtained previouslystringRequired if grantType=refreshTokenno

Response:

NameDescriptionType
resultInterface request resultboolean
codeInterface response valueint
messageThe interface returns a message, "success" on success.string
accessToken-string
expiresInThe timestamp of accessTokennumber
refreshToken-string
reExpiresInThe timestamp of refreshTokennumber
userIdThe user id of the accountstring

Note:

  • The users can cancel the authorization, once canceled, the accessToken and refreshToken will be invalidated immediately.
  • When you call the interface with refreshToken, you get a new accessToken, the accessToken expiration date is refreshed and the original accessToken expires immediately. At the same time, you will get a new refreshToken, the original refreshToken will be invalid, and the validity period of the new refreshToken will not be refreshed.

Request Example:

{
  "appId": "8b037229f05d4846a780f94c01217c86",
  "grantType": "authorizationCode",
  "authCode": "8f8039620d97682f5dc2233c0846f4c9801cd5e98e10b495cf874b01e40dff25",
  "sign": "BBEEgnnb7Ff6FXTI9nnYEFHh79dZa3WW7H61I25ZALuunPuc/VPs2usZuo1cXxZE",
  "signType": "HmacSHA256",
  "refreshToken": ""
}

Response Example:

{
  "result": true,
  "code": 0,
  "message": null,
  "data": {
    "accessToken": "C6cB322UtP14uR6DLgPRtbyBXL+wjb6NFuM1tCXMwly+6RhaCOh27euJvteoBxltRT0RYsGlEGT5aZv/WF8ZPiaNhC+L+cSoR1cnXpxFaThqkuPIWCyAFjQDR433qaeyxISeLGGFjLTxvWlwBAhRqSxTo8ahswpfRUbOHRBVxnGtDp8Ks81bEEYc4zIa0/oFxyo6+eEDPfAU/Drm0Mw/EhFfwc8lLoptF7uo20iNEQ4P73V4INLWkXbSKKOrhTwQyabEGAoOiZ2LMXEN2JxK16zL9GcVNAkaQBwEWYpNaDvX9U/tQp+A+ct/ztpPUxKWaNck1B/+FESh4aK7Jh+RK52K4sQfJL3APiU5pYl3YI4=",
    "expiresIn": 1698390847916,
    "reExpiresIn": 31536000,
    "refreshToken": "chBKBBkUmZ2NHIcTOVKH6AX2wbkeEwA0bbJVd0LZL8+eFmWsTt9NDt78YcOwFGvsPXNABQ/Jicu7vmh8maBsaZBSgV17PyY+JcHv7x8tPYUK2yTO3Nes/mFwvkqEQaTJQ8ofqRYlnY034UojqGW2/cwaK/X3fYtdIZE1GS/X6i7WX04JpASZgaFaS5yuyp2q8Ioze4fTSt+uvtTGKv/aKhfVwhz4cdXfKGWlOt1vTEc4+1OqHjRuTDFfzBT3aD9YIldP142OPYHnBAZzXfnMK3JFNe9vvU7g/XrJR9AqJ86XfZoDkDJCGX0Y+RkxxL7oPbirOpj6PhaeyFiZkayMXQ==",
    "userId": "IfoQ0JsqJ9rUKS7YzhpsHHD33TmqcDufPV6dKTnsvx3qGZ/gYkb5ZgNCKaP5cz04"
  }
}

Get User Info HTTP API

API URL: https://appgallery.lovense.com/remote-dev-api/user/info

Method: POST

Content Type: application/json

Headers:

NameDescriptionTypeRequired
developerTokenDeveloper tokenstringyes
accessTokenThe accessToken obtained in the second stepstringyes

Response:

NameDescriptionType
resultInterface request resultboolean
codeInterface response valueint
messageThe interface returns a message, "success" on success.string
nameThe username that the user agrees to authorizestring

Request Example:

curl -X POST https://appgallery.lovense.com/remote-dev-api/user/info \
-H "Content-Type: application/json" \
-H "developerToken: xxxxxx" \
-H "accessToken: xxxxxxxxxx"

Response Example:

{
  "result": true,
  "code": 0,
  "message": null,
  "data": {
    "name": "lovenseDevTest"
  }
}
Last Updated: 7/3/2024, 1:26:48 AM
Prev
Client API
Next
Error Code
Explore our Forum or Support to get more inspiration or solve your problems.
Discord Channel
It is an online real-time channel where you can communicate directly with our official administrators or many excellent developers.
Forum
It is a place for Lovense developers to communicate, where you can find solutions to problems or get inspired for your projects.
Support
Find documents and tutorials that may be helpful to you.