快速指南

  • 版本網址代稱: Persona/Quick_Setup
  • 版本標題: 快速指南
  • 版本 ID: 362191
  • 建立日期:
  • 建立者: Dwchiang
  • Is current revision?
  • 回應

版本內容

要把 Persona 登入系統加到你的網站,只需要五個步驟:

  1. 在你的網頁中引入 Persona 的 JavaScript 函式庫。
  2. 加上「登入」和「登出」按鈕。
  3. 監聽登入和登出行為。
  4. 驗證使用者的身份 (credential)。
  5. 檢視最佳導入實例。

你应该能在一个下午就建立好并运行,但重要的是:如果你要在你的站点上使用 Persona,请花一点时间订阅 Persona 通知 邮件列表。它流量非常低,只用于通知那些对你站点有负面影响的变更或安全问题。

步骤1:包含 Persona 库

Persona 被设计为跨浏览器且可在全部主要桌面和移动浏览器中工作。

在未来我们期望浏览器提供 Persona 的原生支持,但我们同时提供了一个 JavaScript 库完整地实现了用户界面和客户端部分的协议。通过包含这个库,你的用户会可以用 Persona 登入,无论他们的浏览器是否有原生支持。

一 旦页面中的这个库加载完毕,你需要的 Persona 函数({{ domxref("navigator.id.watch()", "watch()") }}、{{ domxref("navigator.id.request()", "request()") }} 和 {{ domxref("navigator.id.logout()", "logout()") }})会在全局对象 navigator.id 中可用。

要包含 Persona JavaScript 库,你可以把这个 script 标签放进你页面的首部:

<script src="https://login.persona.org/include.js"></script>

必须在每个使用 {{ domxref("navigator.id") }} 中函数的页面里包含这个标签。因为 Persona 始终在开发中,你不应该自行托管 include.js 文件。

步骤2:添加登入/登出按钮

因 为 Persona 被设计为一个 DOM API,你必须在用户点击你站点上的登入或登出按钮时调用函数。要打开 Persona 对话框并提示用户登入,你应该调用 {{ domxref("navigator.id.request()") }} 。而登出要调用 {{ domxref("navigator.id.logout()") }} 。

例如:

var signinLink = document.getElementById('signin');
if (signinLink) {
  signinLink.onclick = function() { navigator.id.request(); };
};

var signoutLink = document.getElementById('signout');
if (signoutLink) {
  signoutLink.onclick = function() { navigator.id.logout(); };
};

那些按钮的是什么样子的?查看我们的品牌资源页面中的预制图片和基于 CSS 的按钮!

步骤3:监视登入/登出行为

要把 Persona 封装成函数,你需要告诉它当用户登入/登出时做什么。调用 {{ domxref("navigator.id.watch()") }} 函数就可以实现,它支持三个三处:

  1. 你站点当前用户的 loggedInEmail ,如果没有则为 null 。你应该在渲染页面的时候动态生成它。

  2. 当触发 onlogin 行为的时候调用的函数。这个函数会被传递一个必须认证的“身份断言”参数。

  3. 当触发 onlogout 行为的时候调用的函数。这个函数不会被传递任何参数。

注意:你必须总是在调用 {{ domxref("navigator.id.watch()") }} 时同时包含 onloginonlogout

例如,如果你现在认为鲍勃已经登入到你的站点,你会这样做:

var currentUser = 'bob@example.com';

navigator.id.watch({
  loggedInUser: currentUser,
  onlogin: function(assertion) {
    // 一个用户已经登入!这是你需要做的:
    // 1. 把断言发送到后端验证并创建一个会话。
    // 2. 更新你的 UI。
    $.ajax({ /* <-- 本例使用了 jQuery,但你也可以用你想用的 */
      type: 'POST',
      url: '/auth/login', // 这是你网站上的一个 URL
      data: {assertion: assertion},
      success: function(res, status, xhr) { window.location.reload(); },
      error: function(res, status, xhr) { alert("登入失败" + res); }
    });
  },
  onlogout: function() {
    // 一个用户已经登出!这是你需要做的:
    // 销毁用户的会话并重定向用户或做后端的调用。
    // 同样,让 loggedInUser 在下个页面加载时变为 null。
    // (这是一个字面的 JavaScript null。不是 false、 0 或 undefined。null。)
    $.ajax({
      type: 'POST',
      url: '/auth/logout', // 这是你网站上的一个 URL
      success: function(res, status, xhr) { window.location.reload(); },
      error: function(res, status, xhr) { alert("登出失败" + res); }
    });
  }
});

在本例中,onloginonlogout 都通过向你站点的后端发送异步 POST 请求来实现。后端随后通常用设定或删除会话 cookie 中的信息来登入或登出用户。之后,如果一切都核对无误,页面重加载来考虑账户的新登录状态。

你当然可以用 AJAX 来不用重加载或重定向来实现,但这超出了本教程的范畴。

必须在每个有登入/登出按钮的页面上调用这个函数。要为用户支持 Persona 加强功能,诸如自动登录和全局登出,你应该在网站上的每个页面都调用这个函数。

步骤4:验证用户证书

Persona 用“身份断言”来代替密码,那是一种类似一次性、单站点的、用户邮件地址捆绑的密码。当用户想要登入时,你的 onlogin 回调会传入一个该用户的断言来调用。在你登入他们前,你必须验证断言的有效性。

在你的服务器上而不是用户浏览器上运行的 JavaScript 中验证断言是极度重要的,因为那很容易伪造。上面的例子用 jQuery 的 $.ajax() 辅助函数来把断言通过 POST/auth/login 来呈递给后端。

一旦你的服务器获得了断言,你如何验证它?最简单的方法是用 Mozilla 提供的辅助服务。简单地把断言以两个参数 POSThttps://verifier.login.persona.org/verify

  1. assertion: 用户提供的身份断言。
  2. audience: 你网站的主机名和端口。你必须在后端硬编码这个值;不要从用户提供的任何数据中派生这个值。

例如,如果你是 example.com,你可以用下面的命令行来测试断言:

$ curl -d "assertion=<ASSERTION>&audience=https://example.com:443" "https://verifier.login.persona.org/verify"

如果它是有效的,你会得到像这样的一个 JSON 响应:

{
  "status": "okay",
  "email": "bob@eyedee.me",
  "audience": "https://example.com:443",
  "expires": 1308859352261,
  "issuer": "eyedee.me"
}

你可以阅读验证服务 API来获知更多关于验证服务的内容。一个 /api/login 实现的使用了 PythonFlask web 框架和 Requests HTTP 库的例子看起来是这样:

@app.route('/auth/login', methods=['POST'])
def login():
    # 请求必须包含我们要验证的断言
    if 'assertion' not in request.form:
        abort(400)

    # 把断言发送给 Mozilla 的验证服务
    data = {'assertion': request.form['assertion'], 'audience': 'https://example.com:443'}
    resp = requests.post('https://verifier.login.persona.org/verify', data=data, verify=True)

    # 验证器响应了吗?
    if resp.ok:
        # 处理响应
        verification_data = json.loads(resp.content)

        # 检查断言是否有效
        if verification_data['status'] == 'okay':
            # 设置一个安全会话 cookie 来登入用户
            session.update({'email': verification_data['email']})
            return resp.content

    # 哎哟,有什么东西不对,放弃
    abort(500)

会话管理可能很像你现有的登录系统。首先的大区别是在验证用户身份采用了检查断言而不是检查密码。另一个不同是确保用户的邮件地址有效来用于 {{ domxref("navigator.id.watch()") }} 的 loggedInEmail 参数

登出很简单:你只需要移除用户的会话 cookie。

步骤5:回顾最佳实践

一旦所有的东西都工作正常并且你已经成功登入和登出你的站点,你应该花一会时间来回顾安全可靠地使用 Persona 的最佳实践

如果你在做一个要作为生产环境的站点,你会想要编写集成的测试来模拟用 Persona 登入或登出用户。要改善 Selenium 中的这个行为,请考虑使用 bidpom 库。mockmyid.compersonatestuser.org 这两个网站也可能会有用。

最后,不要忘记登记加入 Persona 通知 邮件列表,这样会通知你任何安全问题或 Persona API 的向后兼容变更。这个列表的流量非常低:它只用于通知会对你的站点造成负面影响的变更。

版本來源

<p>要把 Persona 登入系統加到你的網站,只需要五個步驟:</p>
<ol>
  <li>在你的網頁中引入 Persona 的 JavaScript 函式庫。</li>
  <li>加上「登入」和「登出」按鈕。</li>
  <li>監聽登入和登出行為。</li>
  <li>驗證使用者的身份 (credential)。</li>
  <li>檢視最佳導入實例。</li>
</ol>
<p>你应该能在一个下午就建立好并运行,但重要的是:如果你要在你的站点上使用 Persona,请花一点时间订阅 <a href="https://mail.mozilla.org/listinfo/persona-notices">Persona 通知</a> 邮件列表。它流量非常低,只用于通知那些对你站点有负面影响的变更或安全问题。</p>
<h2 id=".E6.AD.A5.E9.AA.A41.EF.BC.9A.E5.8C.85.E5.90.AB_Persona_.E5.BA.93">步骤1:包含 Persona 库</h2>
<p>Persona 被设计为跨浏览器且可在<a href="https://developer.mozilla.org/docs/persona/Browser_compatibility">全部主要桌面和移动浏览器</a>中工作。</p>
<p>在未来我们期望浏览器提供 Persona 的原生支持,但我们同时提供了一个 JavaScript 库完整地实现了用户界面和客户端部分的协议。通过包含这个库,你的用户会可以用 Persona 登入,无论他们的浏览器是否有原生支持。</p>
<p>一 旦页面中的这个库加载完毕,你需要的 Persona 函数({{ domxref("navigator.id.watch()", "watch()") }}、{{ domxref("navigator.id.request()", "request()") }} 和 {{ domxref("navigator.id.logout()", "logout()") }})会在全局对象 <code>navigator.id</code> 中可用。</p>
<p>要包含 Persona JavaScript 库,你可以把这个 <code>script</code> 标签放进你页面的首部:</p>
<pre class="brush: html;">
&lt;script src="https://login.persona.org/include.js"&gt;&lt;/script&gt;
</pre>
<p>你<strong>必须</strong>在每个使用 {{ domxref("navigator.id") }} 中函数的页面里包含这个标签。因为 Persona 始终在开发中,你不应该自行托管 <code>include.js</code> 文件。</p>
<h2 id=".E6.AD.A5.E9.AA.A42.EF.BC.9A.E6.B7.BB.E5.8A.A0.E7.99.BB.E5.85.A5.2F.E7.99.BB.E5.87.BA.E6.8C.89.E9.92.AE">步骤2:添加登入/登出按钮</h2>
<p>因 为 Persona 被设计为一个 DOM API,你必须在用户点击你站点上的登入或登出按钮时调用函数。要打开 Persona 对话框并提示用户登入,你应该调用 {{ domxref("navigator.id.request()") }} 。而登出要调用 {{ domxref("navigator.id.logout()") }} 。</p>
<p>例如:</p>
<pre class="brush: js;">
var signinLink = document.getElementById('signin');
if (signinLink) {
  signinLink.onclick = function() { navigator.id.request(); };
};

var signoutLink = document.getElementById('signout');
if (signoutLink) {
  signoutLink.onclick = function() { navigator.id.logout(); };
};
</pre>
<p>那些按钮的是什么样子的?查看我们的<a href="https://developer.mozilla.org/docs/persona/branding">品牌资源</a>页面中的预制图片和基于 CSS 的按钮!</p>
<h2 id=".E6.AD.A5.E9.AA.A43.EF.BC.9A.E7.9B.91.E8.A7.86.E7.99.BB.E5.85.A5.2F.E7.99.BB.E5.87.BA.E8.A1.8C.E4.B8.BA">步骤3:监视登入/登出行为</h2>
<p>要把 Persona 封装成函数,你需要告诉它当用户登入/登出时做什么。调用 {{ domxref("navigator.id.watch()") }} 函数就可以实现,它支持三个三处:</p>
<ol>
  <li>
    <p>你站点当前用户的 <code>loggedInEmail</code> ,如果没有则为 <code>null</code> 。你应该在渲染页面的时候动态生成它。</p>
  </li>
  <li>
    <p>当触发 <code>onlogin</code> 行为的时候调用的函数。这个函数会被传递一个必须认证的“身份断言”参数。</p>
  </li>
  <li>
    <p>当触发 <code>onlogout</code> 行为的时候调用的函数。这个函数不会被传递任何参数。</p>
  </li>
</ol>
<div class="note style-wrap">
  <p><strong>注意:</strong>你必须总是在调用 {{ domxref("navigator.id.watch()") }} 时同时包含 <code>onlogin</code> 和 <code>onlogout</code> 。</p>
</div>
<p>例如,如果你现在认为鲍勃已经登入到你的站点,你会这样做:</p>
<pre class="brush: js;">
var currentUser = 'bob@example.com';

navigator.id.watch({
  loggedInUser: currentUser,
  onlogin: function(assertion) {
    // 一个用户已经登入!这是你需要做的:
    // 1. 把断言发送到后端验证并创建一个会话。
    // 2. 更新你的 UI。
    $.ajax({ /* &lt;-- 本例使用了 jQuery,但你也可以用你想用的 */
      type: 'POST',
      url: '/auth/login', // 这是你网站上的一个 URL
      data: {assertion: assertion},
      success: function(res, status, xhr) { window.location.reload(); },
      error: function(res, status, xhr) { alert("登入失败" + res); }
    });
  },
  onlogout: function() {
    // 一个用户已经登出!这是你需要做的:
    // 销毁用户的会话并重定向用户或做后端的调用。
    // 同样,让 loggedInUser 在下个页面加载时变为 null。
    // (这是一个字面的 JavaScript null。不是 false、 0 或 undefined。null。)
    $.ajax({
      type: 'POST',
      url: '/auth/logout', // 这是你网站上的一个 URL
      success: function(res, status, xhr) { window.location.reload(); },
      error: function(res, status, xhr) { alert("登出失败" + res); }
    });
  }
});
</pre>
<p>在本例中,<code>onlogin</code> 和 <code>onlogout</code> 都通过向你站点的后端发送异步 <code>POST</code> 请求来实现。后端随后通常用设定或删除会话 cookie 中的信息来登入或登出用户。之后,如果一切都核对无误,页面重加载来考虑账户的新登录状态。</p>
<p>你当然可以用 AJAX 来不用重加载或重定向来实现,但这超出了本教程的范畴。</p>
<p>你<strong>必须</strong>在每个有登入/登出按钮的页面上调用这个函数。要为用户支持 Persona 加强功能,诸如自动登录和全局登出,你<strong>应该</strong>在网站上的每个页面都调用这个函数。</p>
<h2 id=".E6.AD.A5.E9.AA.A44.EF.BC.9A.E9.AA.8C.E8.AF.81.E7.94.A8.E6.88.B7.E8.AF.81.E4.B9.A6">步骤4:验证用户证书</h2>
<p>Persona 用“身份断言”来代替密码,那是一种类似一次性、单站点的、用户邮件地址捆绑的密码。当用户想要登入时,你的 <code>onlogin</code> 回调会传入一个该用户的断言来调用。在你登入他们前,你必须验证断言的有效性。</p>
<p>在你的服务器上而不是用户浏览器上运行的 JavaScript 中验证断言是<em>极度</em>重要的,因为那很容易伪造。上面的例子用 jQuery 的 <code>$.ajax()</code> 辅助函数来把断言通过 <code>POST</code> 到 <code>/auth/login</code> 来呈递给后端。</p>
<p>一旦你的服务器获得了断言,你如何验证它?最简单的方法是用 Mozilla 提供的辅助服务。简单地把断言以两个参数 <code>POST</code> 给 <code>https://verifier.login.persona.org/verify</code>:</p>
<ol>
  <li><code>assertion</code>: 用户提供的身份断言。</li>
  <li><code>audience</code>: 你网站的主机名和端口。你必须在后端硬编码这个值;不要从用户提供的任何数据中派生这个值。</li>
</ol>
<p>例如,如果你是 <code>example.com</code>,你可以用下面的命令行来测试断言:</p>
<pre class="brush: bash;">
$ curl -d "assertion=&lt;ASSERTION&gt;&amp;audience=https://example.com:443" "https://verifier.login.persona.org/verify"
</pre>
<p>如果它是有效的,你会得到像这样的一个 JSON 响应:</p>
<pre class="brush: js;">
{
  "status": "okay",
  "email": "bob@eyedee.me",
  "audience": "https://example.com:443",
  "expires": 1308859352261,
  "issuer": "eyedee.me"
}
</pre>
<p>你可以阅读<a href="https://developer.mozilla.org/en-US/docs/BrowserID/Remote_Verification_API">验证服务 API</a>来获知更多关于验证服务的内容。一个 <code>/api/login</code> 实现的使用了 <a href="http://python.org/">Python</a>、<a href="http://flask.pocoo.org/">Flask</a> web 框架和 <a href="http://python-requests.org">Requests</a> HTTP 库的例子看起来是这样:</p>
<pre class="brush: python;">
@app.route('/auth/login', methods=['POST'])
def login():
    # 请求必须包含我们要验证的断言
    if 'assertion' not in request.form:
        abort(400)

    # 把断言发送给 Mozilla 的验证服务
    data = {'assertion': request.form['assertion'], 'audience': 'https://example.com:443'}
    resp = requests.post('https://verifier.login.persona.org/verify', data=data, verify=True)

    # 验证器响应了吗?
    if resp.ok:
        # 处理响应
        verification_data = json.loads(resp.content)

        # 检查断言是否有效
        if verification_data['status'] == 'okay':
            # 设置一个安全会话 cookie 来登入用户
            session.update({'email': verification_data['email']})
            return resp.content

    # 哎哟,有什么东西不对,放弃
    abort(500)
</pre>
<p>会话管理可能很像你现有的登录系统。首先的大区别是在验证用户身份采用了检查断言而不是检查密码。另一个不同是确保用户的邮件地址有效来用于 {{ domxref("navigator.id.watch()") }} 的 <code>loggedInEmail</code> 参数</p>
<p>登出很简单:你只需要移除用户的会话 cookie。</p>
<h2 id=".E6.AD.A5.E9.AA.A45.EF.BC.9A.E5.9B.9E.E9.A1.BE.E6.9C.80.E4.BD.B3.E5.AE.9E.E8.B7.B5">步骤5:回顾最佳实践</h2>
<p>一旦所有的东西都工作正常并且你已经成功登入和登出你的站点,你应该花一会时间来回顾安全可靠地使用 Persona 的<a href="https://developer.mozilla.org/docs/BrowserID/Security_Considerations">最佳实践</a>。</p>
<p>如果你在做一个要作为生产环境的站点,你会想要编写集成的测试来模拟用 Persona 登入或登出用户。要改善 Selenium 中的这个行为,请考虑使用 <a href="https://github.com/mozilla/bidpom" title="https://github.com/mozilla/bidpom">bidpom</a> 库。<a href="https://mockmyid.com/" title="https://mockmyid.com/">mockmyid.com</a> 和 <a href="http://personatestuser.org" title="http://personatestuser.org">personatestuser.org</a> 这两个网站也可能会有用。</p>
<p>最后,不要忘记登记加入 <a href="https://mail.mozilla.org/listinfo/persona-notices">Persona 通知</a> 邮件列表,这样会通知你任何安全问题或 Persona API 的向后兼容变更。这个列表的流量非常低:它只用于通知会对你的站点造成负面影响的变更。</p>
Revert to this revision