You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Symfony的两个跨子域名应用实现单点登录方案咨询

适配多子域名Symfony应用的SSO方案选择与JWT实现指南

方案选型建议

你的场景是同主域下不同子域名的Symfony应用,基于JWT的SSO是最适配的方案,理由如下:

  • 无需额外搭建独立认证中心,两个应用直接通过JWT互信,落地成本低
  • 子域名场景下可通过Cookie传递JWT(配置Cookie的Domain属性为主域名,比如.example.com),安全且用户无感知
  • Symfony生态有成熟的JWT组件支持,适配性强

如果后续需要扩展更多应用,也可以升级为独立认证中心模式,但当前场景下JWT直接互信完全够用。

Symfony下JWT实现SSO的步骤

1. 统一JWT配置(两个应用共享)

在两个Symfony应用中安装lexik/jwt-authentication-bundle:

composer require lexik/jwt-authentication-bundle

生成一次密钥对,复制到两个应用的config/jwt/目录下:

openssl genrsa -out config/jwt/private.pem -aes256 4096
openssl rsa -pubout -in config/jwt/private.pem -out config/jwt/public.pem

确保两个应用的config/packages/lexik_jwt_authentication.yaml配置一致,重点设置:

lexik_jwt_authentication:
    secret_key: '%env(resolve:JWT_SECRET_KEY)%'
    public_key: '%env(resolve:JWT_PUBLIC_KEY)%'
    pass_phrase: '%env(JWT_PASSPHRASE)%'
    token_ttl: 3600 # 按需调整过期时间
    cookie:
        enabled: true
        name: APP_JWT
        domain: '.example.com' # 主域名,确保子域名可读取
        secure: true # 生产环境开启HTTPS时设为true
        http_only: true
        same_site: lax

2. WebApp_A配置:登录后发放JWT并写入Cookie

在WebApp_A的登录逻辑中,登录成功后生成JWT并通过Cookie返回。如果使用Symfony Security表单登录,可在SecurityController的登录方法中添加:

use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Response;

// ...

public function login(AuthenticationUtils $authenticationUtils, JWTTokenManagerInterface $jwtManager, Request $request): Response
{
    // 原有登录逻辑...
    if ($this->getUser()) {
        $token = $jwtManager->create($this->getUser());
        $cookie = Cookie::create('APP_JWT')
            ->setValue($token)
            ->setDomain('.example.com')
            ->setHttpOnly(true)
            ->setSecure($request->isSecure())
            ->setSameSite('lax')
            ->setMaxAge(3600);
        
        return $this->redirectToRoute('home', [], Response::HTTP_OK)->headers->setCookie($cookie);
    }
    // ...
}

3. WebApp_B配置:验证JWT Cookie实现自动登录

在WebApp_B的config/packages/security.yaml中,添加JWT防火墙配置:

security:
    firewalls:
        main:
            lazy: true
            jwt:
                provider: app_user_provider # 需与WebApp_A共享用户数据源(如同一数据库)
            form_login:
                login_path: app_login
                check_path: app_login
            logout:
                path: app_logout

确保WebApp_B的用户提供者能从共享数据源获取用户信息,验证JWT中的用户标识(如username或email)后即可自动登录。

4. 测试SSO流程

  1. 在WebApp_A登录,检查浏览器Cookie中是否存在APP_JWT,域名显示为.example.com
  2. 点击WebApp_A中指向WebApp_B受保护路由的链接,WebApp_B会自动读取Cookie中的JWT,验证通过后直接登录,无需重复输入账号密码

注意事项

  • 两个应用必须共享用户数据(如同一数据库),否则WebApp_B无法识别JWT中的用户
  • 生产环境必须开启HTTPS,防止JWT被窃取
  • 定期更换JWT密钥,避免密钥泄露引发安全问题
  • 如需注销SSO,需在两个应用中同时清除JWTCookie,或添加JWT黑名单机制

内容的提问来源于stack exchange,提问作者marcusm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 04:43:15