Validation

    All requests Plivo makes to your server URLs include X-Plivo-Signature-V3 and X-Plivo-Signature-V3-Nonce HTTP headers. To validate a request and to verify that it originated from Plivo, you must generate a signature at your end and check that it matches the X-Plivo-Signature-V3 parameter in the HTTP header. Read more about signature validation.

    Plivo SDKs provide methods to compute and verify X-Plivo-Signature-V3.

    Arguments

    uri string

    The callback that you want to validate. This uri can be answer_url, url (message callback), message_url, callback_url, action_url, or hangup_url.

    nonce string

    A randomly generated string used to verify requests. You can get the nonce from the event details posted to your callback.

    X-Plivo-Signature-V3 or X-Plivo-Signature-Ma-V3 string

    You can get these values from the event details posted to your callback.

    auth_token string

    Your account Auth Token, which you can get from the overview screen of the Plivo console.

    Response

      true
    

    Example Request

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    
    from flask import Flask, request, make_response, url_for
    import plivo
    from urllib.parse import urlparse, parse_qs
    from plivo import utils
    from plivo import plivoxml
    
    app = Flask(__name__)
    
    @app.route('/speak/', methods=['GET', 'POST'])
    def validate_signature():
        signature = request.headers.get('X-Plivo-Signature-V3', 'signature')
        nonce = request.headers.get('X-Plivo-Signature-V3-Nonce', '12345')
        url = url_for('validate_signature', _external=True)
        auth_token = "your_auth_token"
        method = request.method
        if method == 'GET':
            valid = plivo.utils.validate_v3_signature(
                method, url, nonce, auth_token, signature)
        else:
            params = request.get_json()
            valid = plivo.utils.validate_v3_signature(
                method, url, nonce, auth_token, signature, params)
        print(valid)
        r = plivoxml.ResponseElement()
        speak_params = {
            'loop': '3'
        }
        r.add(plivoxml.SpeakElement("Hello, from Plivo", **speak_params))
        response = make_response(r.to_string())
        response.headers["Content-type"] = "text/xml"
        print(r.to_string())
        return response
    
    
    if __name__ == "__main__":
        app.run(host='0.0.0.0', debug=True)
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    
    require 'sinatra'
    require 'rubygems'
    require 'plivo'
    include Plivo
    include Plivo::XML
    
    get '/speak/' do
    	auth_token = "Your_Auth_Token"
    	signature = headers.fetch("X-Plivo-Signature-V3", "signature")
    	nonce = headers.fetch("X-Plivo-Signature-V3-Nonce", "12345")
    	url = request.url
    	method = "GET"
    	output = Plivo::Utils.valid_signatureV3?(url, nonce, signature, auth_token, method)
    	puts output
    
    	response = Response.new
    	response.addSpeak("Hello, Welcome to Plivo")
    	xml = PlivoXML.new(response)
    	content_type 'text/xml'
    	return xml.to_s
    end
    
    post '/speak/' do
    	auth_token = "your_auth_token"
    	signature = headers.fetch("X-Plivo-Signature-V3", "signature")
    	nonce = headers.fetch("X-Plivo-Signature-V3-Nonce", "12345")
    	url = request.url
    	method = "POST"
    	output = Plivo::Utils.valid_signatureV3?(url, nonce, signature, auth_token, method, params)
    	puts output
    
    	response = Response.new
    	response.addSpeak("Hello, Welcome to Plivo")
    	xml = PlivoXML.new(response)
    	content_type 'text/xml'
    	return xml.to_s
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    
    let express = require('express');
    let app = express();
    app.set('port', (process.env.PORT || 5000));
    app.use(express.static(__dirname + '/public'));
    
    app.all('/speak/', function (request, response) {
        let headers = request.headers;
        console.log(headers);
        let signature = request["X-Plivo-Signature-V3"];
        let nonce = request["X-Plivo-Signature-V3-Nonce"];
        if (!signature) {
            signature = "signature";
        }
        if (!nonce) {
            nonce = "12345";
        }
        let url = request.url;
        let auth_token = "your_auth_token";
        console.log(signature, nonce);
        let method = request.method;
        let validate;
        if (method == "GET") {
            validate = plivo.validateV3Signature(method, url, nonce, auth_token, signature);
        } else {
            let params = request.body;
            validate = plivo.validateV3Signature(method, url, nonce, auth_token, signature, params);
        }
        console.log(validate);
    
        let r = plivo.Response();
        r.addSpeak("Hello from Plivo");
        console.log(r.toXML());
    
        response.set({
            'Content-Type': 'text/xml'
        });
        response.end(r.toXML());
    });
    
    app.listen(app.get('port'), function () {
        console.log('Node app is running on port', app.get('port'));
    });
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    
    <?php
    require 'vendor/autoload.php';
    use Plivo\Exceptions\PlivoValidationException;
    use Plivo\Util\v3SignatureValidation;
    use Plivo\XML\Response;
    
    if (preg_match('/speak/', $_SERVER["REQUEST_URI"])) {
        $auth_token = "your_auth_token";
        $signature = @$_SERVER["X-Plivo-Signature-V3"] ?: 'signature';
        $nonce = @$_SERVER["X-Plivo-Signature-V3-Nonce"] ?: 'nonce';
        $url = 'http' . (isset($_SERVER['HTTPS']) ? 's' : '') . '://' . "{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";
        $method = $_SERVER['REQUEST_METHOD'];
        $SVUtil = new v3SignatureValidation();
        if ($method == "GET") {
            try {
                $valid = $SVUtil->validateV3Signature($method, $url, $nonce, $auth_token, $signature);
            } catch (PlivoValidationException $e) {
                echo("error");
            }
        } else {
            $body = file_get_contents("php://input");
            $params = json_decode($body, true);
            try {
                $valid = $SVUtil->validateV3Signature($method, $url, $nonce, $auth_token, $signature, $params);
            } catch (PlivoValidationException $e) {
                echo("error");
            }
        }
        echo $valid;
        $body = 'Hi, Calling from Plivo';
        $attributes = array(
            'loop' => 3,
        );
        $r = new Response();
        $r->addSpeak($body, $attributes);
        echo($r->toXML());
    } else {
        echo "<p>Welcome to Plivo</p>";
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    
    package plivoexample;
    
    import java.io.IOException;
    import java.net.URLDecoder;
    import java.util.Iterator;
    import java.util.LinkedHashMap;
    import java.util.List;
    import java.util.Map;
    
    import com.plivo.helper.exception.PlivoException;
    import com.plivo.helper.xml.elements.Message;
    import com.plivo.helper.xml.elements.PlivoResponse;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.eclipse.jetty.server.Server;
    import org.eclipse.jetty.servlet.ServletContextHandler;
    import org.eclipse.jetty.servlet.ServletHolder;
    
    import com.plivo.helper.util.*;
    
    public class validateSignature extends HttpServlet {
      private static final long serialVersionUID = 1L;
      @Override
      protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
        String auth_token = "your_auth_token";
        String signature = req.getHeader("X-Plivo-Signature-V3");
        String nonce = req.getHeader("X-Plivo-Signature-V3-Nonce");
        String url = req.getRequestURL().toString();
        String method = req.getMethod();
    
        if(method == "GET") {
          try {
            Boolean isValid = Utils.validateSignatureV3(url, nonce, signature, auth_token, method);
            System.out.println("Valid : " + isValid);
          } catch (PlivoException e) {
            e.printStackTrace();
          }
        }
        else{
          try {
            Map<String, String> params = req.getParameterMap();
            Boolean isValid = Utils.validateSignatureV3(url, nonce, signature, auth_token, method, params);
            System.out.println("Valid : " + isValid);
          } catch (PlivoException e) {
            e.printStackTrace();
          }
        }
    
        PlivoResponse response = new PlivoResponse();
        Speak spk = new Speak("Hello, Welcome to Plivo");
    
        try {
          response.append(spk);
          System.out.println(response.toXML());
          resp.addHeader("Content-Type", "text/xml");
          resp.getWriter().print(response.toXML());
        } catch (PlivoException e) {
          e.printStackTrace();
        }
      }
    
      public static void main(String[] args) throws Exception {
        String port = System.getenv("PORT");
        if(port==null)
          port ="8000";
        Server server = new Server(Integer.valueOf(port));
        ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
        context.setContextPath("/");
        server.setHandler(context);
        context.addServlet(new ServletHolder(new  validateSignature()),"/speak");
        server.start();
        server.join();
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using RestSharp;
    using Plivo.XML;
    using Plivo;
    using Nancy;
    
    namespace plivo_dotnet_app
    {
        public sealed class Program : NancyModule
        {
            public Program()
            {
                Get("/speak/", x =>
                {
                    string signature = Request.Headers["X-Plivo-Signature-V3"].ToString();
                    string nonce = Request.Headers["X-Plivo-Signature-V3_Nonce"].ToString();
                    string auth_token = "your_auth_token";
                    string method = Request.Method;
                    string url = Request.Url;
                    bool valid;
                    Dictionary<string, string> parameters = new Dictionary<string, string>();
                    valid = Plivo.Utilities.XPlivoSignatureV3.VerifySignature(url, nonce, signature, auth_token, method);
                    Debug.WriteLine("Valid : " + valid);
    
                    Plivo.XML.Response resp = new Plivo.XML.Response();
                    resp.AddSpeak("Hello, Welcome to Plivo", parameters);
                    Debug.WriteLine(resp.ToString());
    
                    var output = resp.ToString();
                    var res = (Nancy.Response) output;
                    res.ContentType = "text/xml";
                    return res;
                });
    
                Post<Response>("/speak/", x =>
                {
                    string signature = Request.Headers["X-Plivo-Signature-V3"].ToString();
                    string nonce = Request.Headers["X-Plivo-Signature-V3_Nonce"].ToString();
                    string auth_token = "your_auth_token";
                    string method = Request.Method;
                    string url = Request.Url;
                    bool valid;
                    Dictionary<string, string> parameters = new Dictionary<string, string>();
                    parameters = Request.Form;
                    valid = Plivo.Utilities.XPlivoSignatureV3.VerifySignature(url, nonce, signature, auth_token, method, parameters);
                    Debug.WriteLine("Valid : " + valid);
    
                    Plivo.XML.Response resp = new Plivo.XML.Response();
                    resp.AddSpeak("Hello, Welcome to Plivo", parameters);
                    Debug.WriteLine(resp.ToString());
    
                    var output = resp.ToString();
                    var res = (Nancy.Response) output;
                    res.ContentType = "text/xml";
                    return res;
                });
            }
            
            static void Main(string[] args)
            {
                var p = new Program();
            }
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    
    package main
    
    import (
    	"encoding/json"
    	"fmt"
    	"io/ioutil"
    	"net/http"
    	"reflect"
    	"unsafe"
    
    	"github.com/plivo/plivo-go"
    	"github.com/plivo/plivo-go/xml"
    	"github.com/sirupsen/logrus"
    )
    
    type Message struct {
    	Id   string `json:"id"`
    	Name string `json:"name"`
    }
    
    func BytesToString(b []byte) string {
    	bh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
    	sh := reflect.StringHeader{bh.Data, bh.Len}
    	return *(*string)(unsafe.Pointer(&sh))
    }
    
    func speak(w http.ResponseWriter, request *http.Request) {
    	url := request.Host + request.RequestURI
    	signature := request.Header.Get("X-Plivo-Signature-V3")
    	nonce := request.Header.Get("X-Plivo-Signature-V3-Nonce")
    	method := request.Method
    	authToken := "your_auth_token"
    	var valid bool
    	if method == "GET" {
    		valid = plivo.ValidateSignatureV3(url, nonce, method, signature, authToken)
    	} else {
    		parameters := make(map[string]string)
    		b, err := ioutil.ReadAll(request.Body)
    		defer request.Body.Close()
    		if err != nil {
    			http.Error(w, err.Error(), 500)
    			return
    		}
    
    		var msg Message
    		err = json.Unmarshal(b, &msg)
    		if err != nil {
    			http.Error(w, err.Error(), 500)
    			return
    		}
    
    		var inInterface map[string]interface{}
    		inrec, _ := json.Marshal(msg)
    		json.Unmarshal(inrec, &inInterface)
    		for field, val := range inInterface {
    			parameters[field] = val.(string)
    		}
    
    		w.Header().Set("content-type", "text/xml")
    		valid = plivo.ValidateSignatureV3(url, nonce, method, signature, authToken, parameters)
    	}
    	logrus.Info(valid)
    	response := xml.ResponseElement{
    		Contents: []interface{}{
    			new(xml.SpeakElement).
    				AddSpeak("Go Green, Go Plivo."),
    		},
    	}
    	fmt.Fprintf(w, response.String())
    }
    
    func main() {
    	http.HandleFunc("/speak/", speak)
    	http.ListenAndServe(":5000", nil)
    }