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:
Name | Description | Type | Required |
---|---|---|---|
developerToken | Developer token | string | yes |
Parameters:
Name | Description | Type | Note | Required |
---|---|---|---|---|
appId | Appcation ID | string | Get Appcation ID from App Gallery Console | yes |
grantType | Decide whether to get authCode or refreshToken | string | authorizationCode: used when exchanging authCode for accessToken. refreshToken: used when exchanging refreshToken for accessToken | yes |
authCode | The authCode obtained in the first step | string | Required if grantType=authorizationCode | no |
sign | Sign of authCode. It is used to verify that the authcode is legal. | string | Required if grantType=authorizationCode and use appSecret as encryption key | no |
signType | Encryption method | string | Required if grantType=authorizationCode and HmacSHA256 only for now. | no |
refreshToken | The refreshToken obtained previously | string | Required if grantType=refreshToken | no |
Response:
Name | Description | Type |
---|---|---|
result | Interface request result | boolean |
code | Interface response value | int |
message | The interface returns a message, "success" on success. | string |
accessToken | - | string |
expiresIn | The timestamp of accessToken | number |
refreshToken | - | string |
reExpiresIn | The timestamp of refreshToken | number |
userId | The user id of the account | string |
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:
Name | Description | Type | Required |
---|---|---|---|
developerToken | Developer token | string | yes |
accessToken | The accessToken obtained in the second step | string | yes |
Response:
Name | Description | Type |
---|---|---|
result | Interface request result | boolean |
code | Interface response value | int |
message | The interface returns a message, "success" on success. | string |
name | The username that the user agrees to authorize | string |
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"
}
}