aboutsummaryrefslogtreecommitdiff
path: root/files/it/archive/mozilla/persona/remote_verification_api/index.html
blob: 05a0e1e7b550a3f7357221c201ae5f98aef0842d (plain)
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
---
title: API di verifica remota
slug: Archive/Mozilla/Persona/Remote_Verification_API
translation_of: Archive/Mozilla/Persona/Remote_Verification_API
---
<h2 id="Summary" name="Summary">Summary</h2>
<p>When a user tries to log into a website, their browser generates a data structure called an <em>assertion</em>, which is essentially a cryptographically signed email address. The browser sends this assertion to the web site, which must verify that the assertion is valid before logging the user in.</p>
<p>Assertions can be verified locally, or with an API hosted at <span class="link-https"><code>https://verifier.login.persona.org/verify</code></span>. This page describes how to use the API.</p>
<h2 id="Methods" name="Methods">Method</h2>
<p>HTTP POST request to <code>https://verifier.login.persona.org/verify</code>.</p>
<h3 id="Parameters" name="Parameters">Parameters</h3>
<dl>
 <dt>
  <code>assertion</code></dt>
 <dd>
  The assertion supplied by the user. Available as the first parameter passed to the <code>onlogin</code> function in {{ domxref("navigator.id.watch()") }}.</dd>
 <dt>
  <code>audience</code></dt>
 <dd>
  The protocol, domain name, and port of your site. For example, "<code>https://example.com:443</code>".</dd>
</dl>
<h3 id="Return_values" name="Return_values">Return values</h3>
<p>The call returns a JSON structure containing a <code>status</code> element, which may be either "okay" or "failure". Depending on the value of <code>status</code>, the structure contains additional elements listed below.</p>
<h4 id="okay" name="okay">"okay"</h4>
<p>The assertion is valid.</p>
<p>In this case the JSON structure contains the following additional elements:</p>
<table class="standard-table" style="width: 80%;">
 <tbody>
  <tr>
   <td>"<code>email</code>"</td>
   <td>The address contained in the assertion, for the intended person being logged in.</td>
  </tr>
  <tr>
   <td>"<code>audience</code>"</td>
   <td>The audience value contained in the assertion. Expected to be your own website URL.</td>
  </tr>
  <tr>
   <td>"<code>expires</code>"</td>
   <td>The date the assertion expires, expressed as the <a href="/en/JavaScript/Reference/Global_Objects/Date/valueOf" title="en/JavaScript/Reference/Global_Objects/Date/valueOf">primitive value of a Date object</a>: that is, the number of milliseconds since midnight 01 January, 1970 UTC.</td>
  </tr>
  <tr>
   <td>"<code>issuer</code>"</td>
   <td>The hostname of the identity provider that issued the assertion.</td>
  </tr>
 </tbody>
</table>
<h4 id="failure" name="failure">"failure"</h4>
<p>The assertion is invalid. In this case the JSON structure contains one additional element:</p>
<table class="compact-table">
 <tbody>
  <tr>
   <td><code>"reason"</code></td>
   <td>A string explaining why verification failed.</td>
  </tr>
 </tbody>
</table>
<h2 id="Examples" name="Examples">Examples</h2>
<h3 id="node.js" name="node.js">node.js</h3>
<p>This example uses a node.js server using express.js</p>
<pre class="brush: js">var express = require("express"),
    app = express.createServer(),
    https = require("https"),
    querystring = require("querystring");
/* ... */

// The audience must match what your browser's address bar shows,
// including protocol, hostname, and port
var audience = "http://localhost:8888";

app.post("/authenticate", function(req, res) {
  var vreq = https.request({
    host: "verifier.login.persona.org",
    path: "/verify",
    method: "POST"
  }, function(vres) {
    var body = "";
    vres.on('data', function(chunk) { body+=chunk; } )
        .on('end', function() {
          try {
            var verifierResp = JSON.parse(body);
            var valid = verifierResp &amp;&amp; verifierResp.status === "okay";
            var email = valid ? verifierResp.email : null;
            req.session.email = email;
            if (valid) {
              console.log("assertion verified successfully for email:", email);
              res.json(email);
            } else {
              console.log("failed to verify assertion:", verifierResp.reason);
              res.send(verifierResp.reason, 403);
            }
          } catch(e) {
            console.log("non-JSON response from verifier");
            // bogus response from verifier!
            res.send("bogus response from verifier!", 403);

          }
        });
  });

  vreq.setHeader('Content-Type', 'application/x-www-form-urlencoded');

  var data = querystring.stringify({
    assertion: req.body.assertion,
    audience: audience
  });

  vreq.setHeader('Content-Length', data.length);
  vreq.write(data);
  vreq.end();

  console.log("verifying assertion!");
});

</pre>
<p>via <a class="link-https" href="https://github.com/lloyd/myfavoritebeer.org/blob/06255b960e1f9078bc935c1c7af0662f33c88818/server/main.js#L112">Lloyd Hilaiel</a></p>
<h3 id="PHP" name="PHP">PHP</h3>
<pre class="brush: php">$url = 'https://verifier.login.persona.org/verify';
$assert = filter_input(
    INPUT_POST,
    'assertion',
    FILTER_UNSAFE_RAW,
    FILTER_FLAG_STRIP_LOW|FILTER_FLAG_STRIP_HIGH
);
//Use the $_POST superglobal array for PHP &lt; 5.2 and write your own filter
$params = 'assertion=' . urlencode($assert) . '&amp;audience=' .
           urlencode('http://example.com:80');
$ch = curl_init();
$options = array(
    CURLOPT_URL =&gt; $url,
    CURLOPT_RETURNTRANSFER =&gt; TRUE,
    CURLOPT_POST =&gt; 2,
    //CURLOPT_SSL_VERIFYPEER =&gt; true,   //This currently blocks connection to 'https://verifier.login.persona.org/verify'
    CURLOPT_SSL_VERIFYPEER =&gt; 0,

    CURLOPT_SSL_VERIFYHOST =&gt; 2,
    CURLOPT_POSTFIELDS =&gt; $params
);
curl_setopt_array($ch, $options);
$result = curl_exec($ch);
curl_close($ch);
echo $result;</pre>
<p>Via <a class="link-https" href="https://github.com/codepo8/BrowserID-login-with-PHP/blob/184fdb74c8a554461c262875859968154d09288e/verify.php">Christian Heilmann</a></p>
<h3 id="Java" name="Java" style="line-height: 20px;">Java</h3>
<pre class="brush: java">@Override
protected void doPost(final HttpServletRequest req,
   final HttpServletResponse resp) throws ServletException,
   IOException {

   final String audience = req.getServerName();
   final String assertion = req.getParameter("assertion");
   final Verifier verifier = new Verifier();
   final BrowserIDResponse personaResponse = verifier.verify(assertion,audience);
   final Status status = personaResponse.getStatus();

   if (status == Status.OK) {
     /* Authentication with Persona was successful */
     String email = personaResponse.getEmail();
     log.info("{} has sucessfully signed in", email);
     HttpSession session = req.getSession(true);
     session.setAttribute("email", email);

   } else {
     /* Authentication with Persona failed */
     log.info("Sign in failed...");

   }
}
</pre>
<p>Via <a class="link-https" href="https://github.com/user454322/browserid-verifier">Javier</a></p>
<p> </p>
<p>Note: If you send the assertion and audience parameters as a JSON-object, they <strong>must not</strong> be URL-encoded. If they are sent as regular HTTP POST parameters, as in the example above, they <strong>must</strong> be URL-encoded.</p>