Please note, this is a STATIC archive of website developer.mozilla.org from 03 Nov 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

快速安装

要把 Persona 登录系统添加到你的站点只需要 5 步:

  1. 在你的页面中包含 Persona 的 JavaScript 库。
  2. 添加“登入”和“登出”按钮。
  3. 监视登入和登出行为。
  4. 验证用户证书。
  5. 回顾最佳实现。

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

步骤1:包含 Persona 库

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

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

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

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

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

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

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

因 为 Persona 被设计为一个 DOM API,你必须在用户点击你站点上的登入或登出按钮时调用函数。要打开 Persona 对话框并提示用户登入,你应该调用 navigator.id.request() 。而登出要调用 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 封装成函数,你需要告诉它当用户登入/登出时做什么。调用 navigator.id.watch() 函数就可以实现,它支持三个参数:

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

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

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

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

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

var currentUser = '[email protected]';

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": "[email protected]",
  "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)

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

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

步骤5:回顾最佳实践

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

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

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

文档标签和贡献者

标签: 
 此页面的贡献者: teoli, Arz Yu, YangHanlin, yinian1992
 最后编辑者: teoli,