In my meta application with instagram api with instagram login when I define the "Data deletion request URL" the POST request send to my route with following body content
POST /api/delete HTTP/1.1
Host: 26d5-45-8-19-76.ngrok-free.app
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)
Content-Length: 166
Accept: */*
Accept-Encoding: deflate, gzip
Content-Type: application/x-www-form-urlencoded
X-Forwarded-For: 2a03:2880:30ff:8::
X-Forwarded-Host: 26d5-45-8-19-76.ngrok-free.app
X-Forwarded-Proto: https
signed_request=NybldKYslIBJJfCjH9jIE6PI3ohOKimGpB293v1ojeI.eyJ1c2VyX2lk.......
I can't verify the content using header provided based on the description that provided in following link Data Deletion Request Callback
I did following in the NestJS framwork service
import { Injectable } from '@nestjs/common';
import * as crypto from 'crypto';
@Injectable()
export class SignedRequestService {
private readonly secret = 'appsecret'; // Use your app secret here
parseSignedRequest(signedRequest: string): any | null {
const [encodedSig, payload] = signedRequest.split('.', 2);
// decode the data
const sig = this.base64UrlDecode(encodedSig);
const data = JSON.parse(this.base64UrlDecode(payload));
// confirm the signature
const expectedSig = crypto
.createHmac('sha256', this.secret)
.update(payload)
.digest();
if (Buffer.compare(Buffer.from(sig), expectedSig) !== 0) {
console.error('Bad Signed JSON signature!');
return null;
}
return data;
}
private base64UrlDecode(input: string): string {
const base64 = input.replace(/-/g, '+').replace(/_/g, '/');
return Buffer.from(base64, 'base64').toString('utf-8');
}
}
I found what is the different between header and result and try to fix it, I don't know this is a correct way to verify the result or not but it seems working
parseSignedRequest(signedRequest: string): {
user_id: string;
algorithm: 'HMAC-SHA256';
issued_at: number;
} {
const [encodedSig, payload] = signedRequest.split('.', 2);
// decode the data
const data = JSON.parse(this.base64UrlDecode(payload));
const secret = "app-secret";
// confirm the signature
const expectedSig = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('base64')
.replace('=', '')
.replace(/\+/g, '-')
.replace(/\//g, '_');
if (expectedSig !== encodedSig) {
throw new BadRequestException('Bad Signed JSON signature!');
}
return data;
}
private base64UrlDecode(input: string): string {
const base64 = input.replace(/-/g, '+').replace(/_/g, '/');
return Buffer.from(base64, 'base64').toString('utf-8');
}
I will be happy to get any suggestions