国外persona用户画像
In this article we’ll see how to use the new, future-ready distributed authentication system Mozilla Persona. As the name says, Persona is created and sponsored by the Mozilla Foundation and presents itself as an easier and more secure alternative to OpenID and OAuth.
在本文中,我们将看到如何使用新的,面向未来的分布式身份验证系统Mozilla Persona 。 顾名思义,Persona是由Mozilla基金会创建和赞助的,并以OpenID和OAuth的更轻松,更安全的替代方式呈现。
Mozilla Persona is built upon the BrowserID technology also developed by Mozilla. You can find an expanded explanation of the concepts in the article How BrowserID Works by Lloyd Hilaiel, but I will condense the key points here.
Mozilla Persona是基于Mozilla开发的BrowserID技术构建的。 您可以在Lloyd Hilaiel的文章“ BrowserID的工作原理”中找到有关这些概念的扩展说明,但是我将在此处总结要点。
An email address is an identity and it’s verified by the email provider (such as Gmail, Yahoo, etc.) who serves the role of Primary Identity Authority (or simply primary).
电子邮件地址是一种身份,并且由充当主要身份验证机构 (或简称为primary )的电子邮件提供商(例如Gmail,Yahoo等)进行了验证。
Authentication takes place in the browser. There is no transaction with third-party sites so it’s efficient and privacy-protecting. The browser has the role of Implementation Provider (IP).
身份验证在浏览器中进行。 没有与第三方站点的交易,因此它高效且具有隐私保护。 浏览器具有实施提供商 ( IP )的角色。
In the ideal (future) workflow, the browser implements the navigator.id API natively and email providers are able to act as the primary authority for their users. We can implement a functional workflow today by using the HTML5 implementation provided by Mozilla and the browserid.org server as a Secondary Identity Authority to verify email addresses.
在理想的(未来的)工作流程中,浏览器本机实现navigator.id API,电子邮件提供商可以充当其用户的主要权限。 今天,我们可以使用Mozilla提供HTML5实现和作为辅助身份验证机构的browserid.org服务器提供HTML5实现来验证电子邮件地址,从而实现功能性工作流程。
Let’s say that Mark wants to sign in to the site myfavoritebeer.org using the email address mr.nice.guy@gmail.com. There are three steps to follow:
假设Mark想要使用电子邮件地址mr.nice.guy@gmail.com登录到myfavoritebeer.org网站。 遵循三个步骤:
1. Certificate provisioning If it’s the first time the email address is used as an identity, the browser sends Mark to a secure authentication page at GMail. The browser then generates a key pair (using navigator.id.genKeyPair()) and sends the public key to GMail.
1.证书配置如果是第一次使用电子邮件地址作为身份,浏览器会将Mark发送到GMail的安全身份验证页面。 然后,浏览器会生成密钥对(使用navigator.id.genKeyPair() ),并将公共密钥发送到GMail。
GMail sends back a certificate, a signed package containing the email address, the user’s public key and an expiration date. It’s signed with Gmail’s private key and packaged as a JSON Web Token (JWT), a signed JSON Object.
GMail会发回证书,包含电子邮件地址,用户的公钥和有效期的签名软件包。 它使用Gmail的私钥签名,并打包为JSON Web令牌(JWT)(即已签名的JSON对象) 。
The certificate is stored in the browser keychain along with the private key (using navigator.id.registerVerifiedEmail()) and is used in the next step.
证书与私钥(使用navigator.id.registerVerifiedEmail() )一起存储在浏览器钥匙串中,并在下一步中使用。
If an email provider does not support BrowserID natively, the email is verified by the browserid.org server as a secondary authority. Basically, you receive an email with a link to visit in order to confirm your identity.
如果电子邮件提供者本身不支持BrowserID,则该电子邮件将由browserid.org服务器验证为辅助权限。 基本上,您会收到一封包含要访问的链接的电子邮件,以确认您的身份。
2. Assertion generation The browser generates an assertion, a JWT package proving that Mark owns mr.nice.guy@gmail.com. The package contains the target site (myfavoritebeer.org), an expiration date, and the certificate issued by GMail. It’s all signed with Mark’s private key and sent to myfavoritebeer.org for verification.
2.断言的生成浏览器生成一个断言 ,一个JWT包,证明Mark拥有mr.nice.guy@gmail.com。 该软件包包含目标站点(myfavoritebeer.org),到期日期和GMail颁发的证书。 所有这些都使用Mark的私钥签名并发送到myfavoritebeer.org进行验证。
If the browser does not support BrowserID natively then the operation is performed by fallback JavaScript code provided by Mozilla.
如果浏览器本身不支持BrowserID,则该操作由Mozilla提供的后备JavaScript代码执行。
3. Assertion verification The site myfavoritebeer.org receives and verifies Mark’s request. First it checks the validity period, then it retrieves GMail’s public key to verify the certificate. The certificate contains Mark’s public key which is used to verify the assertion.
3.断言验证网站myfavoritebeer.org接收并验证了Mark的请求。 首先,它检查有效期,然后检索GMail的公钥,以验证证书。 证书包含Mark的公共密钥,用于验证断言。
This step assumes GMail supports BrowserID and shares its public keys. At present, the certificate contains an issued-by property pointing to the secondary authority that generated it.
此步骤假定GMail支持BrowserID并共享其公共密钥。 当前,证书包含一个指向由其生成证书的二级颁发机构的颁发者属性。
If it all goes well Mark is logged in to the site until the assertion expires.
如果一切顺利,Mark将登录到站点,直到断言终止。
The following example uses and extends the information and code from the official Mozilla Persona Quick Setup article in order to obtain a basic yet fully functional system. The buttons use the CSS styles created for Mozilla by Sawyer Hollenshead. The code for the example can be downloaded from GitHub.
以下示例使用并扩展了Mozilla Persona快速安装官方文章中的信息和代码,以获得基本但功能齐全的系统。 这些按钮使用Sawyer Hollenshead为Mozilla创建CSS样式。 该示例的代码可以从GitHub下载。
First here’s a basic index.php file:
首先,这里是一个基本的index.php文件:
<?php // Check if the user is logged in $user = null; if (!empty($_COOKIE['auth'])) { $user = $_COOKIE['auth']; } ?> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>My Favorite Beer - Mozilla Persona Test Code</title> <link rel="stylesheet" href="css/persona/persona-buttons.css"> </head> <body> <h1>My Favorite Beer: a test page for Mozilla Persona</h1> <?php if (!empty($user)) { ?> <p>Hello <strong><?=$user?></strong>!</p> <a href="#" class="persona-button persona-signout"><span>Sign out</span></a> <?php } else { ?> <a href="#" class="persona-button persona-signin"><span>Sign in with Persona</span></a> <?php } ?> <!--jQuery Library from Google--> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> <!--Persona Library from Mozilla--> <script src="https://login.persona.org/include.js"></script> <!-- Our custom code --> <script src="js/mfb.js"></script> </body> </html>I’m storing the authentication info (the email address only) in a cookie variable called auth. The first few PHP lines check this cookie and set a local $user variable accordingly.
我将身份验证信息(仅电子邮件地址)存储在名为auth的cookie变量中。 前几行PHP会检查此Cookie,并相应地设置本地$ user变量。
The $user variable is checked in the main body: if the user is logged in a welcome message is displayed followed by the “Sign out” button. If not the “Sign in” button is displayed by default.
$user变量在主体中进行了检查:如果用户已登录,则显示欢迎消息,然后显示“退出”按钮。 如果不是,则默认显示“登录”按钮。
At the bottom of the page you can find the jQuery library, the Mozilla Persona fallback library, and our custom JavaScript code file mfb.js. In this file I’ve set our custom hooks that link the backend to the Persona API.
在页面底部,您可以找到jQuery库,Mozilla Persona后备库和我们的自定义JavaScript代码文件mfb.js 在此文件中,我设置了自定义钩子,这些钩子将后端链接到Persona API。
(function(window, $, undefined) { // See: http://www.quirksmode.org/js/cookies.html window.readCookie = function(name) { var nameEQ = name + '='; var ca = document.cookie.split(';'); for(var i = 0; i < ca.length; i++) { var c = ca[i]; while (c.charAt(0) == ' ') { c = c.substring(1, c.length); } if (c.indexOf(nameEQ) == 0) { return c.substring(nameEQ.length, c.length); } } return null; }; // Read auth info (the email address) from cookie var currentUser = window.readCookie('auth'); // If the user is not logged in set the default to null if (!currentUser) { currentUser = null; } // The returned value must be URL-decoded if (currentUser != null) { currentUser = decodeURIComponent(currentUser); } navigator.id.watch({ loggedInUser: currentUser, onlogin: function(assertion) { // A user has logged in! Here you need to send the // assertion to your backend for verification and to // create a session and then update your UI. $.ajax({ type: 'POST', url: 'login.php', // This is a URL on your website. data: {assertion: assertion}, success: function(res, status, xhr) { window.location.reload(); }, error: function(xhr, status, err) { alert('Login failure: ' + err); } }); }, onlogout: function() { // A user has logged out! Here you need to tear down the // user's session by redirecting the user or making a call // to your backend. Also, make sure loggedInUser will get // set to null on the next page load. $.ajax({ type: 'POST', url: 'logout.php', // This is a URL on your website. success: function(res, status, xhr) { window.location.reload(); }, error: function(xhr, status, err) { alert('Logout failure: ' + err); } }); } }); $(document).ready(function(){ $('a.persona-signin').click(function(e) { navigator.id.request(); e.preventDefault(); }); $('a.persona-signout').click(function(e) { navigator.id.logout(); e.preventDefault(); }); }); })(window, jQuery);First there’s a quick utility function that reads cookies. Then it tries to read the currentUser variable from the cookie. It’s URL-encoded so we need the built-in decodeURIComponent() function to obtain the unencoded email address. It’s important that this variable contains either the user’s valid email address or the JavaScript null value; any other value will cause an infinite reload loop.
首先,有一个快速的实用程序功能可以读取Cookie。 然后,它尝试从cookie中读取currentUser变量。 它是经过URL编码的,因此我们需要内置的decodeURIComponent()函数来获取未编码的电子邮件地址。 重要的是,此变量必须包含用户的有效电子邮件地址或JavaScript空值。 任何其他值都将导致无限重载循环。
Next we “watch” the required onlogin and onlogout actions by calling the navigator.id.watch() API and passing the details of our PHP backend. The login.php and logout.php scripts are called via Ajax POST by this API.
接下来,我们通过调用navigator.id.watch() API并传递PHP后端的详细信息来“监视”所需的onlogin和onlogout操作。 这个API通过Ajax POST调用login.php和logout.php脚本。
The logout script is pretty simple: it unsets the auth cookie and exits. In a real world application it’s good practice to include a CSRF protection token and perform other security checks.
注销脚本非常简单:它取消设置auth cookie并退出。 在实际应用中,最好的做法是包括CSRF保护令牌并执行其他安全检查。
The login script is responsible for validating the user’s identity with the email provider. In a real app we would also check the user’s identity inside the application’s database.
登录脚本负责通过电子邮件提供商验证用户的身份。 在真实的应用程序中,我们还将在应用程序的数据库中检查用户的身份。
The main flow is:
主要流程是:
<?php // Call the BrowserID API $response = PersonaVerify(); // If the authentication is successful set the auth cookie $result = json_decode($response, true); if ('okay' == $result['status']) { $email = $result['email']; setcookie('auth', $email); } // Print the response to the Ajax script echo $response;First it calls a utility function that encapsulates all the business logic (we’ll see it soon). If the identity check is positive then the auth cookie is set and other post-auth code should be called here; in any case the raw JSON response is returned to the calling script.
首先,它调用一个实用程序函数,该函数封装了所有业务逻辑(我们将很快看到)。 如果身份检查为肯定,则设置身份验证cookie,并在此处调用其他身份验证后代码; 无论如何,原始JSON响应都会返回到调用脚本。
The function PersonaVerify() is responsible for the assertion and certificate verification. It’s important that this step is performed server-side to limit the possibility of malicious code injection. Normally in this function we should retrieve the public key from the identity authority and verify it ourselves, but since the specifications are still in development and the BrowserID protocol is not implemented by email providers, the safe way to do it is perform remote validation with Persona verification service.
PersonaVerify()函数负责声明和证书验证。 必须在服务器端执行此步骤,以限制恶意代码注入的可能性,这一点很重要。 通常,在此功能中,我们应该从身份授权机构中检索公钥并自己进行验证,但是由于规范仍在开发中,并且电子邮件提供商未实现BrowserID协议,因此,安全的方法是使用Persona执行远程验证验证服务。
<?php function PersonaVerify() { $url = 'https://verifier.login.persona.org/verify'; $assert = filter_input( INPUT_POST, 'assertion', FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW|FILTER_FLAG_STRIP_HIGH ); $scheme = 'http'; if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != "on") { $scheme = 'https'; } $audience = sprintf( '%s://%s:%s', $scheme, $_SERVER['HTTP_HOST'], $_SERVER['SERVER_PORT'] ); $params = 'assertion=' . urlencode($assert) . '&audience=' . urlencode($audience); $ch = curl_init(); $options = array( CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => 2, CURLOPT_POSTFIELDS => $params ); curl_setopt_array($ch, $options); $result = curl_exec($ch); curl_close($ch); return $result; }The code for this function comes from the Mozilla Persona developers area.
该功能的代码来自Mozilla Persona开发人员区域。
The assertion parameter is taken from the Ajax POSTed variables and sanitized. The audience parameter is essentially our site URL in the format scheme://host:port, so it’s calculated using the $_SERVER superglobal.
assertion参数取自Ajax POSTed变量并进行了清理。 audience参数本质上是我们的网站URL,格式为scheme:// host:port,因此它是使用$ _SERVER超全局变量来计算的。
Both parameters are encoded and sent using a cURL HTTP POST call to the Persona Verification Service. The result is a JSON string that is returned to the calling script for parsing.
使用cURL HTTP POST调用对这两个参数进行编码并发送给Persona Verification Service。 结果是一个JSON字符串,该字符串返回到调用脚本进行解析。
In a few steps we have easily integrated a new authentication system for our applications. Thanks to the fallback code we can start using it now and be ready when it will be supported natively by both the browser and the email providers.
只需几个步骤,我们就可以轻松地为我们的应用程序集成新的身份验证系统。 由于有了后备代码,我们现在就可以开始使用它了,并且当浏览器和电子邮件提供商都将原生支持它时,就可以使用它了。
If you want a deeper knowledge of the topic you can read the Persona Official Documentation and this article that highlights the differences between Persona and OpenID.
如果您想更深入地了解该主题,可以阅读《 Persona官方文档》 , 该文章重点介绍了Persona和OpenID之间的区别。
That’s all for now, happy coding!
现在就这些,快乐的编码!
Image via Fotolia
图片来自Fotolia
翻译自: https://www.sitepoint.com/authenticate-users-with-mozilla-persona/
国外persona用户画像
相关资源:_国内外用户画像研究综述.pdf