要把 Persona 登录系统添加到你的站点只需要 5 步:
- 在你的页面中包含 Persona 的 JavaScript 库。
- 添加“登入”和“登出”按钮。
- 监视登入和登出行为。
- 验证用户证书。
- 回顾最佳实现。
你应该能在一个下午就建立好并运行,但重要的是:如果你要在你的站点上使用 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()
函数就可以实现,它支持三个参数:
-
你站点当前用户的
loggedInEmail
,如果没有则为null
。你应该在渲染页面的时候动态生成它。 -
当触发
onlogin
行为的时候调用的函数。这个函数会被传递一个必须认证的“身份断言”参数。 -
当触发
onlogout
行为的时候调用的函数。这个函数不会被传递任何参数。
注意:你必须总是在调用 navigator.id.watch()
时同时包含 onlogin
和 onlogout
。
例如,如果你现在认为鲍勃已经登入到你的站点,你会这样做:
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); } }); } });
在本例中,onlogin
和 onlogout
都通过向你站点的后端发送异步 POST
请求来实现。后端随后通常用设定或删除会话 cookie 中的信息来登入或登出用户。之后,如果一切都核对无误,页面重加载来考虑账户的新登录状态。
你当然可以用 AJAX 来不用重加载或重定向来实现,但这超出了本教程的范畴。
你必须在每个有登入/登出按钮的页面上调用这个函数。要为用户支持 Persona 加强功能,诸如自动登录和全局登出,你应该在网站上的每个页面都调用这个函数。
步骤4:验证用户证书
Persona 用“身份断言”来代替密码,那是一种类似一次性、单站点的、用户邮件地址捆绑的密码。当用户想要登入时,你的 onlogin
回调会传入一个该用户的断言来调用。在你登入他们前,你必须验证断言的有效性。
在你的服务器上而不是用户浏览器上运行的 JavaScript 中验证断言是极度重要的,因为那很容易伪造。上面的例子用 jQuery 的 $.ajax()
辅助函数来把断言通过 POST
到 /auth/login
来呈递给后端。
一旦你的服务器获得了断言,你如何验证它?最简单的方法是用 Mozilla 提供的辅助服务。简单地把断言以两个参数 POST
给 https://verifier.login.persona.org/verify
:
assertion
: 用户提供的身份断言。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
实现的使用了 Python、Flask 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.com 和 personatestuser.org 这两个网站也可能会有用。
最后,不要忘记登记加入 Persona 通知 邮件列表,这样会通知你任何安全问题或 Persona API 的向后兼容变更。这个列表的流量非常低:它只用于通知会对你的站点造成负面影响的变更。