我正在Laravel中构建一个多域/多商店电子商务应用程序,并希望在用户从一个商店更改为另一个商店时保持登录。
但据我所知,Laravel的Auth服务将登录用户保存在会话中,其他域无法访问这些会话。
有没有一种方法(也许是一个包)可以实现这一点,而不会让我的应用程序容易出现安全问题?
提前感谢!
- 捕获域A中的会话id
Session::getId()
- 通过HTTP POST将捕获的会话id发送到域B
- 访问域B
$sessionid_from_domainA = $_POST['session_from_A']
中发送的会话id - 在域B
Session::setId($sessionid_from_domainA)
中设置会话 - 在域B
Session::start()
中启动会话
如果你想在多个子域之间共享会话,那么你必须设置域名config/session.php已经设置了域名。
示例:如果你有new.Example.com和test.Example.com,那么你必须将域名设置为Example.com
'domain' => env('SESSION_DOMAIN_URL','.example.com')
那里的解决方案对我很有效,特别是设置域,然后清除我的浏览器Cookie&隐藏物
-
在域A上创建像这样的图像
<img src="https://DOMAINB.com/setcookie?id={{ Session::getId() }}" style="display:none;" />
-
在域B上创建这样的路由:
Route::get('setcookie', function(){
Session::setId($_GET['id']);
Session::start();
return 'Cookie created';
});`
- 完成,现在您应该能够通过
$user = Auth::User;
获得您的用户
我知道这并不是我们所要求的,但出于开发和测试的目的,我这样做了:
在config/session.php中,尝试更改这一行
'path' => '/',
进入这个
'path' => '/;SameSite=None; secure',
允许我从不同的域进行身份验证。
现在,您应该能够编写一个简单的中间件来防止不需要的主机。像这样的东西。
namespace AppHttpMiddleware;
use IlluminateHttpRequest;
use Closure;
class TrustedHosts{
public function handle($request, Closure $next){
//$host = $request->getHost();
$host = $request->headers->get('origin');
$enviroment = env('APP_ENV');
if ( $enviroment == 'development' ) {
$trustedHosts = array('localhost', 'dev.mydomain.com');
}
else {
$trustedHosts = array('anotherdomain.com', 'mydomain.com');
}
$isHostTrusted = in_array($host, $trustedHosts);
if ( !$isHostTrusted ) return response("I'm a teapot", 418); //Or any other code and message that you prefer.
return $next($request);
}
}
并将其分组到包含会话内容的中间件组中。
我也在研究类似的单一登录系统,仍在努力寻找解决方案,但这是一个开始http://laravel.io/forum/03-14-2014-multiple-domains-how-to-share-login
在laravel上,您可以将/app/config/session.php驱动程序更改为cookie
编辑:
这就是我所做的。
您可以使用像素图像跨域共享cookie。例如,当你登录domain1.com时,你想在domain2.com上创建一个cookie,登录domain1..com后,你需要有这样的
<img src="http://www.domain2.com/create-cookie?param=hash">
在domain2.com上面的路线:
- 将首先检查用户是否已登录
- 如果它没有登录,将读取哈希(例如电子邮件地址),检查是否有用户使用该电子邮件,并在那里登录,还设置cookie
您可以手动设置会话cookie将注册到哪个域,从而使它们在不同的站点上持久存在。只需在以下部分编辑config/session.php
:
<?php
/*
|--------------------------------------------------------------------------
| Session Cookie Domain
|--------------------------------------------------------------------------
|
| Here you may change the domain of the cookie used to identify a session
| in your application. This will determine which domains the cookie is
| available to in your application. A sensible default has been set.
|
*/
'domain' => null,
?>
不过,您仍然被限制在一个顶级域中。因此,您可以使用store1.shops.com
和store2.shops.com
共享会话,但不能使用myshop.com
和shopsmart.com
。
如果您需要这种格式的东西,那么创建一个身份验证服务并使用访问令牌来验证凭据可能会更好。你也可以看看像OneLogin这样的服务。
基于Chirag Prajapati的这个答案。Yo可以在env条目中使用$_SERVER['HTTP_HOST']
:
来自/config/session.php
'domain' => env('SESSION_DOMAIN', $_SERVER['HTTP_HOST']),
然后从应用程序根目录:php artisan config:clear
,不要注意警告消息,只需确保最后您已获得Configuration cache cleared!
。通过这种方式,您的应用程序会话将在您拥有的任何域上正常工作。