Nic*_*ico 76
你的问题太具体了,不能给出准确的答案.如果您尝试让用户使用Google帐户登录您的网站,请在此处进行说明.
另一方面,如果您尝试让用户使用一个帐户登录您控制的多个网站,请按以下步骤操作:
使您站点上的所有登录链接指向集中登录页面,但包括有关用户来自链接的位置的信息.例如:
<a href='http://login.example.com/login.php?source=my.other.site.com/foo/bar'>log in!!</a>
Run Code Online (Sandbox Code Playgroud)
然后,一旦用户成功登录,您就会将用户重定向回原始站点,同时传递有关经过身份验证的用户所需的任何信息.
但是,您还需要确保人们不能通过向URL添加必要的身份验证参数来绕过您的身份验证机制.这可以通过以参数的HMAC-SHA-256形式包括签名以及存储在登录服务器和始发站点上的秘密来完成.(对于使用SSO系统的每个站点,此密钥最好不同.)
<?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);
?>
Run Code Online (Sandbox Code Playgroud)
然后,在原始站点中,如果签名匹配,则用户已登录.将有关登录用户的信息存储在会话变量(不是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'];
}
}
?>
Run Code Online (Sandbox Code Playgroud)
请注意,我正在使用PHP 5.6中添加的功能:hash_equals.如果低于5.6,则可以使用此替换函数,该函数使用双HMAC验证实现计时安全比较功能:
function hash_equals($a, $b) {
$key = mcrypt_create_iv(128, MCRYPT_DEV_URANDOM);
return hash_hmac('sha512', $a, $key) === hash_hmac('sha512', $b, $key);
}
Run Code Online (Sandbox Code Playgroud)
这显然是一个非常粗略的实施,但它应该是一个不错的起点.
| 归档时间: |
|
| 查看次数: |
67757 次 |
| 最近记录: |