# User Payload
This section explains how will you generate user payload string that will be used in Config initialization. User payload generation is accomplished with the following 3 steps:
# Form Your User Data
The user payload must include the following fields in your data:
{
"user_id": "string user id",
"user_name": "string user name",
"user_avatar_url": "string user avatar url",
"user_followings": [
"string user id 1",
"string user id 2",
"string user id 3"
],
"user_creator_tags": [
"string user creator tag 1",
"string user creator tag 2",
"string user creator tag 3"
],
"user_consumer_tags": [
"string user consumer tag 1",
"string user consumer tag 2",
"string user consumer tag 3"
],
"expiration_time": integer timestamp in miliseconds
}
WARNING
All of the fields should be presented in your data.
# Encrypt Your Data
User payload should be encrypted using AES Encryption in CBC mode with 256 Key size in bits. The payload is encrypted with initialization-vector and secret-key. Initialization-vector is 16 characters long whereas secret-key is 32 characters. When the Storyly Moments instance is created, random initialization-vector and secret-keys are generated along with the Storyly Moments token.
You can use sample encryption functions:
WARNING
This sample contains code from CommonCrypto so you need to import it.
func encrypt(data: Data, operation: CCOperation) throws -> Data {
var outLength = Int(0)
var outBytes = [UInt8](repeating: 0, count: input.count + kCCBlockSizeAES128)
var status: CCCryptorStatus = CCCryptorStatus(kCCSuccess)
input.withUnsafeBytes { rawBufferPointer in
let encryptedBytes = rawBufferPointer.baseAddress!
Data(Array("Storyly Moments Initialization Vector".withUnsafeBytes { rawBufferPointer in
let ivBytes = rawBufferPointer.baseAddress!
Data(Array("Storyly Moments Secret Key".utf8)).withUnsafeBytes { rawBufferPointer in
let keyBytes = rawBufferPointer.baseAddress!
status = CCCrypt(operation,
CCAlgorithm(kCCAlgorithmAES128),
CCOptions(kCCOptionPKCS7Padding),
keyBytes,
key.count,
ivBytes,
encryptedBytes,
input.count,
&outBytes,
outBytes.count,
&outLength)
}
}
}
guard status == kCCSuccess else { throw Error.cryptoFailed(status: status) }
let encryptedData = Data(bytes: &outBytes, count: outLength)
return encryptedData
}
}
func encodeUserData(userData: [String: AnyHashable]) -> Data? {
return try? JSONSerialization.data(withJSONObject: userPayload)
}
let sampleUserData: [String: AnyHashable] = [
"user_id" to "string user id",
"user_name" to "string user name",
"user_avatar_url" to "string user avatar url",
"user_followings" to [ "string user id 1" ...],
"expiration_time" to integer timestamp in miliseconds
]
let encodedData = encode(userData: sampleUserData)
let encryptedData = try? encrypt(data: encodedData, operation: CCOperation(kCCEncrypt))
WARNING
The user payload is valid if it can be decrypted with the initialization vector and secret key of the Storyly Moments instance and if its expiration time is not expired.