Laravel8.x实现跨站登录

作者: 温新

分类: 【Laravel】

阅读: 2088

时间: 2021-11-14 11:55:45

如有一个系统A,系统A下有很多子系统,共享用户信息,在子系统中登录了,其他系统不要再次进行登录。除了跨站登录外,还有单点登录也可以实现。今天学习的是跨站登录,记录一下。

第一步:创建两个项目,分别为主系统和子系统

# 主系统
composer create-project laravel/laravel demo.com
# 子系统
composer create-project laravel/laravel sub.demo.com

第二步:配置域名

# demo.com 主系统域名(顶级域名)
demo.com
# sub.demo.com 子系统域名(二级域名)
sub.demo.com

第三步:创建数据库并修改 .env文件连接数据库

# demo.com 主系统数据库名
2021_demo
# sub.demo.com 子系统数据库名
2021_sub_demo

主系统和子系统分别在.env文件中配置对应的数据库

第四步:使用迁移文件生成数据表

# demo.com 主系统 && sub.demo.com
# 两个系统中都要执行这个命令
php artisan migrate

第五步:主系统和子系统引入脚手架

主系统和子系统都要执行如下操作

composer require laravel/ui
php artisan ui bootstrap --auth
npm install
npm run dev

安装完成后在浏览器中分别访问主系统demo.com和子系统sub.demo.com就能在右上角看到Log inRegister

第六步:配置sub.demo.com子系统

1)配置sub.demo.com子系统数据库连接到主系统

// 位置:sub.demo.com 子系统
// config/database.php
    'connections' => [
        // 连接到主数据库
        'demo_mysql' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            // 主数据库
            'database' => '2021_demo',
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
            ]) : [],
        ],
     ]

我这里主系统与子系统的数据库账号、密码是一样的,因此只修改了数据库名。

2)子系统User模型类配置连接

// 位置:子系统
// sub.demo.com
// app/Models/User.php

// 子系统用户模型中新增如下两个配置
// 连接到主系统数据库,demo_mysql是在database.php配置文件中
// 配置连接到主系统的名字
protected $connection = 'demo_mysql';
// 使用的数据表
protected $table      = 'users';

第七步:简单测试

1)浏览中访问主系统demo.com/register并注册一个用户

2)sub.demo.com子系统中获取主系统注册的用户

// 位置:sub.demo.com 子系统
// routes/web.php

// 获取主系统中的用户
Route::get('sub', function(){
    dd(\App\Models\User::all());
});

3)浏览器中访问子系统sub.demo.com/sub,可以看到获取到了主系统的用户信息了。

4)查看两个系统数据库中的users表,发现只主系统的users表中有用户数据。

第八步:配置基于数据库的session共享驱动

1)主系统和子系统都执行如下操作

php artisan session:table
php artisan migrate

执行完后,会在数据库中生成一个sessions表,用于存储session信息

2)修改驱动为数据库驱动

// .env

// 主系统和子系统的驱动都设置为database
SESSION_DRIVER=database

3)分别访问demo.comsub.demo.com

# 主系统数据库
mysql> select * from 2021_demo.sessions\G;
*************************** 1. row ***************************
           id: 0XBn9XXqJ6fA3yGO5Lx0IjkURT5PVbIawvezRphV
      user_id: NULL
   ip_address: 127.0.0.1
   user_agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36
      payload: 省略该信息,太长了
last_activity: 1636888685
1 row in set (0.00 sec)

# 子系统数据库
mysql> select * from 2021_sub_demo.sessions\G;
*************************** 1. row ***************************
           id: CZBCGqcAEEMWp3IUWh8LYKO8ROXcbgXwtde0f5Z0
      user_id: NULL
   ip_address: 127.0.0.1
   user_agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36
      payload: 省略该信息,太长了
last_activity: 1636888738
1 row in set (0.00 sec)

可以看到user_id为NULL,说明用户没有登录,用户登录后,user_id将记录用户的ID。

4)配置session共享

// 位置:子系统
// config/session.php

// 将子系统连接主系统的session
'connection' => 'demo_mysql',

注意:此时,主系统中的sessions表中只有一条记录。子系统中的seesion连接修改到主系统后,再次访问子系统sub.demo.com生,就会发现,在主系统中的sessions表多出了一条session记录,这个记录就是子系统的session信息。

第九步:跨站登录的实现

1)修改主系统和子系统的session域名

// config/session.php
'domain' => '.demo.com',

主系统和子系统的domain值设置成一样。

2)将主系统中的APP_KEY值覆盖子系统的APP_KEY值。

// 主系统
// .env
APP_KEY=base64:788KCi6RQZH3/fTm5wr04CGFOdMR1Ht7GvHk7JL15WM=
    
// 子系统
// .env
APP_KEY=base64:788KCi6RQZH3/fTm5wr04CGFOdMR1Ht7GvHk7JL15WM=    

3)删除主系统数据库sessions表中的数据

4)清除浏览器缓存,并访问主系统和子系统,将看到主系统数据库中sessions表中只有一条session记录。

第十步:跨站登录实现的测试

1)子系统中使用第七步在主主系统中注册的用户进行登录。

访问:sub.demo.com/login进行登录,子登录登录成功

2)访问主系统demo.com,发现已经处于登录状态。

3)在主系统中退出,然后在访问子系统,发现子已经系统退出

4)在主系统中进行登录,然后刷新子系统,发现子系统已登录。

请登录后再评论