跳转至

PHP

使用 OAuth,您可以借助 Authany 为原生 PHP 应用添加用户身份验证。

本指南将介绍如何在普通 PHP Web 应用中实现 OAuth 2.0 登录,并以 Authany 作为身份提供方。

您将学到什么

读完本文后,您将学到以下内容:

  • 如何创建 Authany 应用
  • 如何启用邮箱和密码登录
  • 如何在 PHP 应用中使用 Authany 登录
  • 如何从 Authany 获取用户信息
  • 如何使用刷新令牌
  • 最后,如何登出用户并撤销访问令牌。

准备工作

跟随本指南操作,您需要准备以下内容:

  • PHP 运行环境(例如在 Windows 设备上离线测试用的 XAMPP)
  • 一个 Authany 账号。如果还没有账号,可以免费注册。
  • 已安装 Composer(PHP 包管理器)
  • 您常用的代码编辑器(例如 VS Code)。

我们将构建什么

在本指南中,我们将构建一个基础 PHP 应用,让用户可以使用注册时的邮箱和密码登录。

用户登录成功后,应用会用其邮箱地址向用户显示欢迎信息。如果用户尚未登录,应用会显示“注册”或“登录”链接。

下面的截图展示了该应用的用户界面效果:

如何用 Authany 为 PHP 添加用户身份验证

现在让我们深入了解将 Authany 集成到 PHP 应用的具体步骤。

第 1 部分:配置 Authany 应用

本节将介绍配置 Authany 应用的步骤,我们的 PHP 网站将连接到这个应用。所有配置都在 Authany 管理台中完成。

步骤 1:设置 Authany 应用

第一步是在 Authany 管理台中创建一个新应用,或配置一个已有的应用。

为此,请登录 Authany 管理台,选择您的项目(如果还没有项目,请创建一个新项目)。在项目控制台中,进入应用部分,按下图所示输入新应用的详细信息:

完成后,点击“保存”按钮继续。然后点击“下一步”,查看应用的配置页面。

应用配置页面包含 Client ID 和 Client Secret 等基本信息,本教程后面会用到,请记下这些值。

除了基本信息外,您还可以在这里找到端点和授权重定向 URI 等其他配置信息。

步骤 2:授权重定向 URI

授权重定向 URI 部分包含一个链接,指向您希望 Authany 在用户登录后将其重定向到的页面。

请将授权重定向 URI 的值更新为您应用中的某个页面。以我们的示例 PHP 应用为例,该值为 http://localhost,因为我们计划使用 XAMPP 离线测试运行。请记下这个值,后面步骤中会用到。

第 2 部分:实现 PHP 项目

本部分将介绍如何实现一个使用 OpenID Connect(OIDC)标准与 Authany 交互的 PHP 网站。

步骤 1:创建 PHP 项目

在电脑上创建一个新的 PHP 项目,并在项目文件夹的根目录下添加一个 index.php 文件。

在 index.php 中添加以下代码,创建示例应用的用户界面。

<?php
$appUrl = "REPLACE WITH YOUR AUTHGEAR PROJECT URL";
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>PHP Demo - Home</title>
</head>
<body style="background-color: #DEDEDE">
    <div style="max-width: 650px; margin: 16px auto; background-color: #FFFFFF; padding: 16px;">
        <h3>Hello world!</h3>
        <p>This demo app shows you how to add user authentication to your app using Authgear</p>
        <p>Checkout <a href="https://docs.authany.com/">docs.authgear.com</a> to learn more about adding Authgear to your apps.</p>

        <p><a href="login.php">Login</a></p>
        <p><a href="logout.php">Logout</a></p>
    </div>
</body>
</html>

注意:上面代码中的“登录”和“登出”链接目前分别指向 login.php 和 logout.php,我们稍后会创建这两个文件。

步骤 2:将 Authany 配置添加到 PHP 项目

在这一步中,我们会将 Authany 应用的配置添加到 PHP 项目中。

我们将使用 OAuth 2.0 Client 这个 PHP 包来完成配置。

您可以从 GitHub 手动安装该包,或者在 PHP 项目的根目录下运行以下命令通过 Composer 安装:

composer require league/oauth2-client

安装好包之后,在 PHP 项目文件夹中创建一个新的 config.php 文件,并添加以下代码:

<?php
require 'vendor/autoload.php';

$appUrl = "PLACE_YOUR_PROJECT_URL_HERE";
$clientID = "PLACE_YOUR_CLIENT_ID_HERE";
$clientSecret = "PLACE_YOUR_CLIENT_SECRET_HERE";
$redirectUri = "PLACE_YOUR_REDIRECT_URI_HERE";

$provider = new \League\OAuth2\Client\Provider\GenericProvider([
    'clientId'                => $clientID,    // The client ID assigned to you by the provider (authgear).
    'clientSecret'            => $clientSecret,    // The client secret is assigned to you by the provider.
    'redirectUri'             => $redirectUri, // The authorized Redirect URI you specified in your authgear app.
    'urlAuthorize'            => $appUrl.'/oauth2/authorize',
    'urlAccessToken'          => $appUrl.'/oauth2/token',
    'urlResourceOwnerDetails' => $appUrl.'/oauth2/userInfo',
    'scopes' => 'openid offline_access'
]);
?>

注意:请将 clientId、clientSecret、redirectUri 的值替换为您在步骤 1 中创建的 Authany 应用对应的值。

要从 Authany 获取刷新令牌,必须包含 offline_access 作用域。

步骤 3:添加登录授权

我们应用的登录流程如下:

  1. 用户点击“登录”按钮
  2. 用户会被重定向到 Authany 授权页面,可以使用邮箱和密码,或您为 Authany 项目启用的任何其他登录方式登录。
  3. 用户会带着授权码被重定向回您的网站。

为了实现上述流程,您需要在项目根目录下创建一个 login.php 文件,并在该文件中添加以下代码:

<?php
include "config.php";

if (!isset($_GET['code'])) {
    // Fetch the authorization URL from the provider; this returns the
    // urlAuthorize option and generates and applies any necessary parameters
    // (e.g. state).
    $authorizationUrl = $provider->getAuthorizationUrl();

    // Redirect the user to the authorization URL.
    header('Location: ' . $authorizationUrl);
    exit;
}
?>

此时,如果您在浏览器中运行示例应用,并点击 index.php 中的“登录”链接,应用应该会重定向到 Authany 登录页面。登录成功后,您会被重定向回之前在项目配置中指定的重定向 URL。

Authany 会重定向到您的授权重定向 URI,并在 URL 中附带 code 等额外参数,或附带错误信息。code 参数的值就是您的授权码。下一步,我们会用这个授权码来生成访问令牌。

步骤 4:获取访问令牌并请求用户信息

通常,登录成功后,您会希望使用当前用户的信息,在应用中提供个性化体验。

在这一步中,我们会再次使用 PHP OAuth 2.0 Client 与我们的 Authany 应用交互。

首先,打开 index.php,找到包含以下代码的那一行:

$appUrl = "REPLACE WITH YOUR AUTHGEAR PROJECT URL";

将上面这一行替换为以下代码:

include "config.php";
session_start();

// if code is set, get access token
if (isset($_GET['code'])) {
    $code = $_GET['code'];

    try {
        $accessToken = $provider->getAccessToken('authorization_code', [
            'code' => $code
        ]);
        $_SESSION['accessToken'] = $accessToken;
        $_SESSION['refreshToken'] = $accessToken->getRefreshToken(); //store refresh token so that you can use it later
    } catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) {
        // Failed to get the access token or user details.
        exit($e->getMessage());
    }
}

上面的代码会用重定向中返回的授权码换取访问令牌,然后将访问令牌存储在 PHP 会话中,以便我们在后续访问受保护资源的请求中使用该令牌。

现在我们已经拿到访问令牌,接下来试着获取当前用户的详细信息。为此,请像下面这样更新 index.php 中的 HTML 部分:

<div style="max-width: 650px; margin: 16px auto; background-color: #FFFFFF; padding: 16px;">
        <h3>Hello world!</h3>
        <p>This demo app shows you how to add user authentication to your app using Authgear</p>
        <p>Checkout <a href="https://docs.authany.com/">docs.authgear.com</a> to learn more about adding Authgear to your apps.</p>
        <?php
        if (isset($_SESSION['accessToken'])) {

            //if access token exists in session, attempt to fetch user info
            $storedAccessToken = $_SESSION['accessToken'];
            $resourceOwner = $provider->getResourceOwner($storedAccessToken);
            $userInfo = $resourceOwner->toArray();

            echo "Welcome back " . $userInfo['email'];
            echo "<br/>";
            echo '<a href="">Logout</a>';

        } else { ?>
        <p><a href="login.php">Login</a></p>

        <?php
        } 
        ?>
    </div>

现在再次在浏览器中测试应用,登录后您应该会看到如下页面:

我们已经成功使用 Authany 作为身份提供方,为 PHP 应用添加了用户身份验证。上面的页面会显示一条欢迎信息,其中包含用户在 Authany 项目中注册所用的邮箱地址。您还可以通过 $userInfo 变量的值显示用户的其他信息。

步骤 5:获取并使用刷新令牌

在 OAuth 2.0 中,当客户端应用用授权码换取访问令牌时,令牌端点返回的响应中通常会包含一个刷新令牌。

访问令牌会在一段时间后过期。因此,我们可以使用刷新令牌来请求新的访问令牌,而无需让应用用户重新登录。在这一步中,我们会介绍如何使用刷新令牌。

在上一步中,我们把刷新令牌的值存储在了 $_SESSION['refreshToken'] 变量中。因此,要获取刷新令牌,只需读取该变量的值即可。

现在,在 index.php 中添加以下代码,读取并使用刷新令牌来获取新的访问令牌:

首先,找到包含以下代码的那一行:

$resourceOwner = $provider->getResourceOwner($storedAccessToken);

将该行替换为以下代码块:

if ($storedAccessToken->hasExpired()) {              
    $newAccesstoken = $provider->getAccessToken('refresh_token', [
        'refresh_token' => $_SESSION['refreshToken']
    ]);

    $_SESSION['accessToken'] = $newAccesstoken;
    $resourceOwner = $provider->getResourceOwner($newAccesstoken);
} else {
    $resourceOwner = $provider->getResourceOwner($storedAccessToken);
}

注意: 要从 Authany 获取刷新令牌,必须在 OAuth 2.0 作用域中包含 offline_access。

步骤 6:登出

Authany 提供了一个令牌撤销端点,您可以用它撤销刷新令牌及与之关联的所有访问权限。

要使用令牌撤销端点将用户登出应用,请在项目目录中创建一个新的 logout.php 文件,并添加以下代码:

<?php 
include "config.php";
session_start();
if (isset($_SESSION['accessToken'])) {
    $options = [];
    $options['headers']['content-type'] = 'application/x-www-form-urlencoded';
    $options['body'] = http_build_query(['token'=>$_SESSION['refreshToken']]);
    $request = $provider->getRequest(
        'POST',
        $appUrl. '/oauth2/revoke',
        $options
    );
    $provider->getResponse($request);

    $_SESSION['accessToken'] = null;
    $_SESSION['refreshToken'] = null;
}

上面的代码会撤销您的刷新令牌,并删除所有会话变量。

小结

在本文中,我们介绍了如何在没有使用任何框架的普通 PHP Web 应用中开始集成 Authany。

我们还实践了一个示例:使用 Authany 的授权码获取访问令牌,然后用该令牌访问用户信息端点。

这里有我们示例应用的完整源代码,托管在 GitHub 上。

使用 Authany 还能做更多事情,您可以继续查看文档主页上的更多主题,深入学习。