搜索
首页后端开发php教程在 Laravel 中实现和测试社交名流身份验证

Implementing & testing Socialite authentication in Laravel

Laravel Socialite 是一个第一方 Laravel 包,可帮助开发人员在其应用程序中实现 OAuth 和 OAuth2 社交身份验证。它内置了对 Facebook、Twitter、Google、LinkedIn、GitHub、GitLab 和 Bitbucket 的支持。社交名流可以通过社区包支持其他提供商。

这篇文章将:

  • 解释社交名流做什么和不做什么。
  • 展示如何通过 Socialite 将 Google 身份验证集成到新的 Laravel 项目中。
  • 展示测试社交名流的示例。

TLDR:您可以在我的 GitHub 上查看已完成的项目。如果您只想阅读完整的代码,请看一下它。

Laravel Socialite 做什么和不做什么?

Socialite 是一个小包,其主要 API 主要由两个主要方法组成:

  • Socialite::driver($authProvider)->redirect() 将把用户重定向到指定的身份验证提供者,通过 URL 参数将任何必要的信息传递给提供者。
  • Socialite::driver($authProvider)->user() 检索从身份验证提供者传回的用户数据并将其提供给端点。

还有针对设置范围和可选参数的附加支持方法。您可以在社交名流文档中阅读有关它们的信息。

社交名流不会执行以下操作:它将这些功能的实现留给开发人员:

  • ❌ 创建存储社交身份验证数据所需的数据库表或列。
  • ❌ 创建身份验证过程中不存在的用户。
  • ❌ 在 OAuth 流程成功后对用户进行身份验证。
  • ❌ 刷新 OAuth 令牌。

先决条件:创建 Google Cloud 项目

我们将建立一个小型社交项目,允许用户通过 Google 进行身份验证。为此,您必须创建一个 Google 应用。

首先创建一个新的 Google Cloud 项目,然后为该项目配置 OAuth 同意屏幕。将用户类型设置为外部,然后启用以下范围:

  • .../auth/userinfo.email
  • .../auth/userinfo.profile

配置同意屏幕后,通过访问 Google Cloud 凭据页面创建 OAuth 2.0 客户端 ID。保留客户端ID客户端密钥:我们稍后将在项目中使用它们。

使用 Socialite 设置一个最小的 Laravel 项目

创建一个新的 Laravel 项目:

laravel new socialite-tests

从安装程序中选择以下选项:

 ┌ Would you like to install a starter kit? ────────────────────┐
 │ No starter kit                                               │
 └──────────────────────────────────────────────────────────────┘

 ┌ Which testing framework do you prefer? ──────────────────────┐
 │ Pest                                                         │
 └──────────────────────────────────────────────────────────────┘

 ┌ Which database will your application use? ───────────────────┐
 │ SQLite                                                       │
 └──────────────────────────────────────────────────────────────┘

 ┌ Would you like to run the default database migrations? ──────┐
 │ Yes                                                          │
 └──────────────────────────────────────────────────────────────┘

切换到项目目录并安装Socialite。

laravel new socialite-tests

创建新的迁移。

 ┌ Would you like to install a starter kit? ────────────────────┐
 │ No starter kit                                               │
 └──────────────────────────────────────────────────────────────┘

 ┌ Which testing framework do you prefer? ──────────────────────┐
 │ Pest                                                         │
 └──────────────────────────────────────────────────────────────┘

 ┌ Which database will your application use? ───────────────────┐
 │ SQLite                                                       │
 └──────────────────────────────────────────────────────────────┘

 ┌ Would you like to run the default database migrations? ──────┐
 │ Yes                                                          │
 └──────────────────────────────────────────────────────────────┘

将以下代码放入database/migrations中新创建的迁移文件中:

cd socialite-tests
composer require laravel/socialite

此迁移添加了当用户成功进行身份验证时由社交名流提供的字段。在我们的实现中,为了简单起见,我们将这些字段直接添加到用户表中。如果您想支持比 Google 更多的提供商,您可能需要创建一个单独的表来存储每个用户的多个提供商。

我们将密码设置为可为空,因为如果用户仅通过 Google 进行身份验证,则永远不会设置密码。如果您的应用允许社交身份验证密码身份验证,则当用户尝试通过密码登录时,您必须验证密码不为空或为空。

运行迁移。

php artisan make:migration add_socialite_fields_to_users

在 config/services.php 中,将以下代码块添加到 services 数组的末尾。您可以在配置文档中找到有效社交名流服务名称的完整列表。

<?php // database/migrations/2024_12_31_075619_add_socialite_fields_to_users.php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string('google_id')->default('');
            $table->string('google_token')->default('');
            $table->string('google_refresh_token')->default('');

            // If your app allows both password and social logins, you
            // MUST validate that the password is not blank during login.
            // If you do not, an attacker could gain access to an account
            // that uses social login by only knowing the email.
            $table->string('password')->nullable()->change();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn('google_id');
            $table->dropColumn('google_token');
            $table->dropColumn('google_refresh_token');
            $table->string('password')->nullable(false)->change();
        });
    }
};

使用您在“先决条件”部分中创建的 Google 应用中的凭据,将以下内容添加到 .env。

php artisan migrate

将routes/web.php的内容替换为以下代码。

// config/services.php

'google' => [
    'client_id' => env('GOOGLE_CLIENT_ID'),
    'client_secret' => env('GOOGLE_CLIENT_SECRET'),
    'redirect' => '/auth/google/callback',
],

此文件中的新代码实现了以下路由:

  • 重定向到 Google 以使用适当的信息进行社交登录。
  • 处理来自 Google 的回调。此路由在登录时创建或更新用户,然后对他们进行身份验证,并将他们重定向到主页。
  • 注销经过身份验证的用户。

最后,将 resources/views/welcome.php 的内容替换为以下标记。

# .env

GOOGLE_CLIENT_ID="your-google-client-id"
GOOGLE_CLIENT_SECRET="your-google-client-secret"

完成后,我们可以通过运行开发服务器来手动测试应用程序。

<?php // routes/web.php

use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
use Laravel\Socialite\Facades\Socialite;
use Laravel\Socialite\Two\InvalidStateException;
use Laravel\Socialite\Two\User as OAuth2User;

Route::get('/', function () {
    return view('welcome');
});

Route::get('/auth/google/redirect', function () {
    return Socialite::driver('google')->redirect();
});

Route::get('/auth/google/callback', function () {
    try {
        /** @var OAuth2User $google_user */
        $google_user = Socialite::driver('google')->user();
    } catch (InvalidStateException $exception) {
        abort(400, $exception->getMessage());
    }

    $user = User::updateOrCreate([
        'email' => $google_user->email,
    ], [
        'google_id' => $google_user->id,
        'name' => $google_user->name,
        'google_token' => $google_user->token,
        'google_refresh_token' => $google_user->refreshToken,
    ]);

    Auth::login($user);
    return redirect('/');
});

Route::get('/auth/logout', function () {
    Auth::logout();
    return redirect('/');
});

当您点击使用 Google 登录链接时,您应该完成 OAuth2 流程并被重定向到主页,您可以在其中查看有关来自 Google 的新创建用户的信息。

用害虫测试社交名流

我们的手动测试有效,但我们希望通过自动化测试来验证我们将来不会意外破坏此功能。

我们可以使用以下命令创建一个新的测试文件。

<!-- resources/views/welcome.php -->



    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Laravel Socialite Testing Example</title>


    <h1 id="Laravel-Socialite-Testing-Example">Laravel Socialite Testing Example</h1>
    @if (auth()->check())
        <p>User is authenticated.</p>
        <p>Name: {{ auth()->user()->name }}</p>
        <p>Email: {{ auth()->user()->email }}</p>
        <p><a href="/auth/logout">Logout</a></p>
    @else
        <p>User is not authenticated.</p>
        <p>
            <a href="/auth/google/redirect">Login with Google</a>
        </p>
    @endif


将新创建的tests/Feature/AuthRoutesTest.php 的内容替换为以下内容。

php artisan serve

测试如何进行

在测试重定向路由时,我们测试Socialite是否重定向到正确的URL并传递正确的URL参数。

在测试回调路由时,我们模拟了 Socialite。模拟不是我最喜欢的选择:在理想的世界中,我们可以将 Socialite 替换为另一个 OAuth2 实现,并且我们的测试仍然有效。但是,没有直接的方法来连接社交名流发送的授权授予请求以装饰访问令牌。正因为如此,模拟是测试社交名流的最实用的方法。

通过 Mockery 模拟流畅的 API 非常乏味:您必须从最终调用开始并向后进行。

这是我们的回调端点调用的 Socialite 方法。

laravel new socialite-tests

以下是如何通过 Mockery 来嘲笑它:

 ┌ Would you like to install a starter kit? ────────────────────┐
 │ No starter kit                                               │
 └──────────────────────────────────────────────────────────────┘

 ┌ Which testing framework do you prefer? ──────────────────────┐
 │ Pest                                                         │
 └──────────────────────────────────────────────────────────────┘

 ┌ Which database will your application use? ───────────────────┐
 │ SQLite                                                       │
 └──────────────────────────────────────────────────────────────┘

 ┌ Would you like to run the default database migrations? ──────┐
 │ Yes                                                          │
 └──────────────────────────────────────────────────────────────┘

最后,我们进行了一项测试,以确保直接导航到 OAuth 流程之外的回调 URL 会返回 400 状态代码。我们将对 Socialite::driver('google')->user() 的调用包装在 try/catch 块内的回调端点中。如果我们没有将 Socialite 调用包装在 try/catch 块中,并且有人在浏览器中输入了回调 URL,则端点将引发带有 HTTP 500 状态代码的异常。如果您的团队设置了 500 个状态代码的监控,则可能会导致某人在半夜收到寻呼。

总结

这是一个最小的集成,还有很多可以实现的功能。如果我们要实现与社交提供商的集成,其中用户的电子邮件可能会更改,则此实现将不起作用,因为它与电子邮件地址匹配。如果用户可以在我们的应用程序中更改他们的电子邮件地址,那么由于同样的原因,此实现也将不起作用。但是,现在您已经了解了如何测试 Socialite,您可以为这些场景编写测试并修改底层实现,以便它们通过。

在我了解如何构建自己的实现、如何测试它以及我应该考虑什么之前,我阅读了很多有关 Socialite 的博客文章和论坛帖子。我想对其中的一些人表示感谢。

  • 我如何为 Laravel Socialite 支持的应用程序编写集成测试,作者:Stefan Zweifel
  • ServerSideUp 论坛:社交名流最佳实践,对话
  • Stack Overflow:如何测试 Laravel Socialite
  • Stack Exchange:链接或不链接社交登录与匹配的电子邮件
  • Stack Exchange:处理关联的社交帐户和潜在的孤儿

如果您有兴趣深入挖掘,请阅读这些内容。另外,如果您对本文的第 2 部分感兴趣,请告诉我,我将深入探讨处理多个社交提供商、处理用户更改电子邮件地址或处理刷新令牌。

以上是在 Laravel 中实现和测试社交名流身份验证的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
在Laravel中使用Flash会话数据在Laravel中使用Flash会话数据Mar 12, 2025 pm 05:08 PM

Laravel使用其直观的闪存方法简化了处理临时会话数据。这非常适合在您的应用程序中显示简短的消息,警报或通知。 默认情况下,数据仅针对后续请求: $请求 -

PHP记录:PHP日志分析的最佳实践PHP记录:PHP日志分析的最佳实践Mar 10, 2025 pm 02:32 PM

PHP日志记录对于监视和调试Web应用程序以及捕获关键事件,错误和运行时行为至关重要。它为系统性能提供了宝贵的见解,有助于识别问题并支持更快的故障排除

php中的卷曲:如何在REST API中使用PHP卷曲扩展php中的卷曲:如何在REST API中使用PHP卷曲扩展Mar 14, 2025 am 11:42 AM

PHP客户端URL(curl)扩展是开发人员的强大工具,可以与远程服务器和REST API无缝交互。通过利用Libcurl(备受尊敬的多协议文件传输库),PHP curl促进了有效的执行

简化的HTTP响应在Laravel测试中模拟了简化的HTTP响应在Laravel测试中模拟了Mar 12, 2025 pm 05:09 PM

Laravel 提供简洁的 HTTP 响应模拟语法,简化了 HTTP 交互测试。这种方法显着减少了代码冗余,同时使您的测试模拟更直观。 基本实现提供了多种响应类型快捷方式: use Illuminate\Support\Facades\Http; Http::fake([ 'google.com' => 'Hello World', 'github.com' => ['foo' => 'bar'], 'forge.laravel.com' =>

在Codecanyon上的12个最佳PHP聊天脚本在Codecanyon上的12个最佳PHP聊天脚本Mar 13, 2025 pm 12:08 PM

您是否想为客户最紧迫的问题提供实时的即时解决方案? 实时聊天使您可以与客户进行实时对话,并立即解决他们的问题。它允许您为您的自定义提供更快的服务

解释PHP中晚期静态结合的概念。解释PHP中晚期静态结合的概念。Mar 21, 2025 pm 01:33 PM

文章讨论了PHP 5.3中引入的PHP中的晚期静态结合(LSB),从而允许静态方法的运行时分辨率调用以获得更灵活的继承。 LSB的实用应用和潜在的触摸

自定义/扩展框架:如何添加自定义功能。自定义/扩展框架:如何添加自定义功能。Mar 28, 2025 pm 05:12 PM

本文讨论了将自定义功能添加到框架上,专注于理解体系结构,识别扩展点以及集成和调试的最佳实践。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)