如何使用 PHP 进行单点登录?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5062569/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 16:42:24  来源:igfitidea点击:

How to do single sign-on with PHP?

php

提问by Egglabs

Eg: Gmail, Orkut, Wava and feedburner login access using single google account.

例如:使用单个谷歌帐户登录 Gmail、Orkut、Wava 和 feedburner。

回答by Nico

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.

你的问题太不具体了,无法给出准确的答案。如果您尝试让用户使用 Google 帐户登录您的网站,请参阅此处

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.

然后,一旦用户成功登录,您将用户重定向回原始站点,同时传递您需要的有关已验证用户的任何信息。

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.)

但是,您还需要确保人们不能通过向 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);
?>

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):

然后,在原始站点中,如果签名匹配,则用户已经登录。将有关登录用户的信息存储在会话变量(不是 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'];
  }
}

?>

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 comparisonfunction using double HMAC verification:

请注意,我用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);
}

This is obviously a very crude implementation, but it should be a decent starting point.

这显然是一个非常粗糙的实现,但它应该是一个不错的起点。

回答by xaav

If you are wanting a cross-site central login system, I would recommend something like OpenID. You could run your own server, and then have only one login for multiple sites.

如果你想要一个跨站点的中央登录系统,我会推荐像OpenID这样的东西。您可以运行自己的服务器,然后只需一次登录即可登录多个站点。

回答by alex

Have one central registry for authenticated users.

为经过身份验证的用户设置一个中央注册表。

All applications access this parent to get authentication.

所有应用程序都访问此父级以获取身份验证。

Cross domain cookies can be done with special links with a nonce, and a new cookie is created on the new domain if the nonce matches a valid token from the parent.

跨域 cookie 可以通过带有 nonce 的特殊链接来完成,如果 nonce 与来自父级的有效令牌匹配,则会在新域上创建一个新 cookie。