App Instance (Client Side)

Note:

There are two types of App Instance, the below info refers to the App Instance that gets returned in the client:

  • In iframe endpoints
  • For external dashboard apps when clicking the "Open App" button 
  • For apps with an external package picker when clicking the "Upgrade App" button.

For the API instance see here, note though that most new apps will use both of these, and while there are many similarities they're not identical.

The Wix platform accesses each of your app endpoints using a URL with a set of query parameters that describes the endpoint context. The most important of these is the instance parameter.

The instance parameter enables you to identify the site and the Wix user, and to verify that the calling party is indeed Wix. The identity of the calling party is verified by a digital signature that's generated using the app secret key, which is generated during the app registration process in the Wix Developers Center.

The instance parameter is composed of two parts that are separated by a dot:

  1. Signature: HMACSHA-256 signature. Generated using the App Secret Key and the data part of the instance. The signature is Base64 URL encoded.
  2. Data: A Base64 URL encoded JSON object. This JSON includes the instance properties, listed below. You’ll need to decode the data to see these properties.

Example of an instance query parameter:

Copy
1
// Signature Data
2
vrinSv2HB9tqbnJ6RSwoMgVamAIxpmmsA0I6eAan960.eyJpbnN0YW5jZUlkIjoiYWZmNTAxNmQtMjkxNC00ZDYzLWEzOGMtYTZk...

Instance properties

These properties make up the data part of the Instance parameter. They’re encoded with base64 URL, so you’ll need to decode it.

Important: Dashboard Security

It's critical that you block access when aid is returned in the instance parameter. This means the user trying to access the dashboard is anonymous – i.e., not the site's owner or a collaborator (these can be identified by the uid).

FieldDescription
instanceIdThe instance ID of the app within Wix. Read more about the App Instance ID below.
signDateThe date of the payload signature.
uidThe ID of the Wix user or site member who is logged in
permissionsThe permission set of the Wix user or site member:
Note: To check if the site owner is logged in, compare the uid to the siteOwnerId property.
ipAndPort (deprecated)The user's current IP address and port number.
vendorProductId(Optional, appears if the site owner upgraded the app) The Plan ID of the package the site owner purchased.
aidThe ID of an anonymous site visitor.
originInstanceId(Optional, appears in copied sites) The instance ID of the app in the original website.
siteOwnerIdThe ID of the site owner. When this value is the same as the uid, it means the site owner is logged in.

Note:

The siteOwnerId for a given instanceId can change. If a site owner transfers the site to another user, the existing instanceId is now linked to the new site owner. For example - User A transfers the site to User B. The app keeps its instanceId - but is now linked to User B's siteOwnerId.

App Instance ID

The App Instance ID is the unique identifier of the app within the website. Read more about the app instance ID.

Note for "old" SDK users:

To get the instanceId of your app in a given site, use the Wix.Utils.getInstanceIdetinstanceid SDK method.

Important:

Consent policy will be passed as a query param in the iframe URL – but it's for internal use and will not necessarily be accurate. Your app should not depend on it at all.

JSON example

Copy
1
{
2
"instanceId":"bf296da1-75ce-48e6-9f72-14b7148d4fa2",
3
"signDate":"2015-12-10T06:57:37.201Z",
4
"uid":"da32cbf7-7f8b-4f9b-a97e-e67f3072ce92",
5
"permissions":"OWNER",
6
"ipAndPort":"91.199.119.13/35734",
7
"vendorProductId":null,
8
"originInstanceId":"c38e4e00-dcc1-433e-9e90-b332def7b342",
9
"siteOwnerId":"da32cbf7-7f8b-4f9b-a97e-e67f3072ce92"
10
}

Parsing examples

Node.JS

Copy
1
const CryptoJS = require("crypto-js");
2
function verifyInstance(instance, secret) {
3
// spilt the instance into signature and data
4
var pair = instance.split('.');
5
var signature = decode(pair[0], 'binary');
6
var data = pair[1];
7
// sign the data using hmac-sha1-256
8
var hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, secret);
9
hmac.update(data);
10
var hash = decode(hmac.finalize().toString(CryptoJS.enc.Base64), 'binary')
11
return (signature === hash)
12
}
13
function decode(data, encoding) {
14
encoding = encoding === undefined ? 'utf8' : encoding
15
var buf = Buffer.from(data.replace(/-/g, '+').replace(/_/g, '/'), 'base64')
16
return encoding ? buf.toString(encoding) : buf;
17
}

PHP

Copy
1
public static function &isWixRequest() {
2
3
list( $code, $data ) = explode( '.', $_GET[ 'instance' ] );
4
5
if ( base64_decode( strtr( $code, "-_", "+/" ) ) != hash_hmac( "sha256", $data, '[APP_SECRET]', TRUE ) ) {
6
die(); // Report error
7
}
8
9
if ( ( $json = json_decode( base64_decode( $data ) ) ) === null ) {
10
die(); // Report error
11
}
12
return $json;
13
}

Java

Copy
1
----------------------------------------------------------------------
2
The following example uses the apache commons-codec library for Base64 encoding and Jackson for JSON parsing.
3
4
The Maven dependencies of those libraries are:
5
6
commons-codec
7
commons-codec
8
1.6
9
10
com.fasterxml.jackson.core
11
jackson-databind
12
2.0.4
13
14
-----------------------------------------------------------------------
15
16
import java.util.Arrays;
17
import javax.crypto.Mac;
18
import javax.crypto.spec.SecretKeySpec;
19
20
import com.fasterxml.jackson.databind.JsonNode;
21
import com.fasterxml.jackson.databind.ObjectMapper;
22
23
import org.apache.commons.codec.binary.Base64;
24
25
public class WixSignatureDecoder {
26
27
public final static JsonNode decodeSignature(final String signedInstance, final String secretKey) throws Exception {
28
// initialization
29
final SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), "HMACSHA256");
30
final Mac mac = Mac.getInstance("HMACSHA256");
31
mac.init(secretKeySpec);
32
33
// split the signed-instance
34
Base64 base64 = new Base64(256, null, true);
35
int idx = signedInstance.indexOf(".");
36
String signature = signedInstance.substring(0, idx);
37
String encodedJson = signedInstance.substring(idx+1);
38
39
byte[] sig = base64.decode(signature.getBytes());
40
byte[] mySig = mac.doFinal(encodedJson.getBytes());
41
if (!Arrays.equals(mySig, sig)) {
42
throw new Exception("signatures do not match");
43
}
44
45
// objectMapper is jackson interface for reading JSON - one JSON serialization library in java
46
return objectMapper.readTree(new String(base64.decode(encodedJson)));
47
}
48
}

Ruby

Copy
1
def parse_instance_data(signed_instance)
2
APP_SECRET = 'YOUR_APP_SECRET_GOES_HERE'
3
signature, encoded_json = signed_instance.split('.', 2)
4
5
# Need to add Base64 padding to make base64 decode work in Ruby. (ref: http://stackoverflow.com/questions/4987772/decoding-facebooks-signed-request-in-ruby-sinatra)
6
7
encoded_json_hack = encoded_json + ('=' * (4 - encoded_json.length.modulo(4)))
8
9
json_str = Base64.decode64(encoded_json_hack)
10
11
hmac = OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, APP_SECRET, encoded_json)
12
13
# bug in ruby. why are there '=' chars on urlsafe_encode ?!
14
15
my_signature = Base64.urlsafe_encode64(hmac).gsub('=','')
16
17
raise "the signatures do not match" if (signature != my_signature)
18
19
JSON.parse(json_str)
20
21
end

Padding

The Base64 spec indicates that for URL-Safe Base64, the padding characters at the end of the encoded character (=) are optional. Wix encoding does not add the padding character.

In Ruby or Python, you should add the padding to the Base64 encoded values that you get from Wix.

Was this helpful?
Yes
No