如何使用PHP进行单点登录? [英] How to do single sign-on with PHP?
问题描述
例如:使用单个Google帐户访问Gmail,Orkut,Wava和feedburner.
Eg: Gmail, Orkut, Wava and feedburner login access using single google account.
推荐答案
您的问题过于具体,无法给出准确的答案.如果您尝试让用户使用Google帐户登录到您的网站,则记录为这里.
Your question is too unspecific to give a precise answer. If you're trying to let users log in to your website using Google accounts, it's documented here.
另一方面,如果您试图让您的用户登录到使用一个帐户控制的多个网站,则可以这样做:
On the other hand, if you're trying to let your users sign in to several websites you control with one account, here's how you can do it:
使您站点上的所有登录链接都指向一个集中式登录页面,但在链接中包括有关用户来源的信息.例如:
Make all login links on your sites point to a centralized login page, but include information about where the user came from in the link. For example:
<a href='http://login.example.com/login.php?source=my.other.site.com/foo/bar'>log in!!</a>
然后,一旦用户成功登录,就可以将用户重定向回原始站点,同时传递有关身份验证用户所需的任何信息.
Then, once the user has logged in successfully, you redirect the user back to the original site while passing along whatever information you need about the authenticated user.
但是,您还需要确保人们不能只是通过向URL添加必要的身份验证参数来规避身份验证机制.这可以通过包含参数的HMAC-SHA-256形式的签名以及存储在登录服务器和原始站点上的密钥来完成. (最好是,使用您的SSO系统的每个站点的此密钥都应该不同.)
However, you also need to make sure that people can't just circumvent your authentication mechanism by adding the necessary authentication parameters to the URL. This can be done by including a signature in the form of an HMAC-SHA-256 of the parameters plus a secret that's stored on both login server and the originating site. (Preferably this key should be different for each site using your SSO system.)
<?php
$MySecretKey = 'Nobody Will Ever Guess This!!';
// Generate signature from authentication info + secret key
$sig = hash(
'sha256',
$user->id . $user->email,
$MySecretKey
);
// Make sure we're redirecting somewhere safe
$source = parse_url($_GET['source']);
if(in_array($source->host, $list_of_safe_hosts))
$target = 'http://'.$source->host.$source->path;
// Send the authenticated user back to the originating site
header('Location: '.$target.'?'.
'user_id='.$user->id.
'&user_email='.urlencode($user->email).
'&sig='.$sig);
?>
然后,在原始站点中,如果签名与用户匹配,则该用户已经登录.将有关登录用户的信息存储在会话变量(不是cookie)中:
Then, in the originating site, if the signature matches the user is already logged in. Store the info about the logged in user in session variables (not a cookie):
<?php
$MySecretKey = 'Nobody Will Ever Guess This!!';
// Set not logged in by default
$user_id = 0;
$user_email = '';
if(intval($_GET['user_id']) && !$_SESSION['user_id']) // Someone trying to log in?
{
// See if they have the right signature
if (hash_equals(hash('sha256', intval($_GET['user_id']).$_GET['user_email'], $MySecretKey), $sig)) {
$_SESSION['user_id'] = intval($_GET['user_id']);
$_SESSION['user_email'] = $_GET['user_email'];
}
}
?>
请注意,我正在使用PHP 5.6中添加的函数: hash_equals
.如果您低于5.6,则可以使用此替代函数来实现双HMAC的noreferrer>定时安全比较功能验证:
Note that I'm using a function added in PHP 5.6: hash_equals
. If you're on lower than 5.6, you can use this substitute function which implements a timing-safe comparison function using double HMAC verification:
function hash_equals($a, $b) {
$key = mcrypt_create_iv(128, MCRYPT_DEV_URANDOM);
return hash_hmac('sha512', $a, $key) === hash_hmac('sha512', $b, $key);
}
这显然是一个非常粗糙的实现,但它应该是一个不错的起点.
This is obviously a very crude implementation, but it should be a decent starting point.
这篇关于如何使用PHP进行单点登录?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!