Invalid Shopify Multipass Request

Viewed 408

I am trying to implement multipass login of shopify using python by referring shopify-multipass library. PHP code for the same is working properly and giving correct multipass login token which is referred from documentation of multipass. When I use url from result, it shows me "Invalid Multipass Request". I tried all possible solutions suggested from Shopify Community.How to fix this? Output

Here is the code:

class Multipass:
def __init__(self, secret):
    key = SHA256.new(secret.encode('utf-8')).digest()
    self.encryptionKey = key[0:16]
    self.signatureKey = key[16:32]

def generateToken(self, customerDataHash):
    customerDataHash['created_at'] = datetime.datetime.utcnow().isoformat()
    cipherText = self.encrypt(json.dumps(customerDataHash))
    return urlsafe_b64encode(cipherText + self.sign(cipherText))

def generateURL(self, customerDataHash, url):
    token = self.generateToken(customerDataHash)
    return '{0}/account/login/multipass/{1}'.format(url, token)

def encrypt(self, plainText):
    plainText = self.pad(plainText)
    iv = get_random_bytes(AES.block_size)
    cipher = AES.new(self.encryptionKey, AES.MODE_CBC, iv)
    return iv + cipher.encrypt(plainText.encode('utf-8'))

def sign(self, secret):
    return HMAC.new(self.signatureKey, secret, SHA256).digest()

def pad(self, s):
    return s + (AES.block_size - len(s) % AES.block_size) * chr(AES.block_size - len(s) % AES.block_size)

and calling function

data = JSONParser().parse(request)
customer_data = dict(email=data['email'], return_to=data['returnUrl'], first_name=data['firstName'], last_name=data['lastName'], identifier=data['username'], company=data['companyName'], phone=data['mobile'])
if data['set_address']:
    address = {"first_name": data['firstName'], "last_name": data['lastName'], "phone": data['mobile'], "address1": data['address'],
               "city": data['city'],"state": data['state'], "country": data['country'], "pincode": data['pincode'], "company":  data['companyName']}
    customer_data["addresses"] = address
multipass = Multipass(SHOPIFY_SECRET)
token = multipass.generateToken(customer_data)
link = "{}account/login/multipass/{}".format(SHOPIFY_ROOT_URL, token)
if token:
    data = {"token": token, "link": link}
    response = helper.generateStandardResponse(0, "Token generated successfully", data, True)
    return Response(response, status=status.HTTP_200_OK)
else:
    response = helper.generateStandardResponse(105, "Error in generating token", {}, False)
    return Response(response, status=status.HTTP_200_OK)
1 Answers

Ran into the same issue, turned out Shopify and Python have conflicting ideas as to what ISO 8601 output should be. Try using strftime instead

Replace:

customerDataHash['created_at'] = datetime.datetime.utcnow().isoformat()

with:

customerDataHash['created_at'] = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')

Worked for me

Related