xero 软件学习_使用PHP与Xero连接

xero 软件学习

In previous posts, we demonstrated connecting to Xero using only an OAuth 2.0 library. We’ve provided examples in NodeJS, Java, .NET, Ruby, GoLang and in this post we look at PHP.

在以前的文章中,我们演示了仅使用OAuth 2.0库连接到Xero。 我们在NodeJSJava ,中提供了示例。 NETRubyGoLang ,在本文中,我们介绍PHP。

What are some reasons a developer might choose to build with just an OAuth 2.0 library and not the official Xero PHP SDK?

开发人员可能选择仅使用OAuth 2.0库而不使用官方Xero PHP SDK进行构建的一些原因是什么?

  1. You have an existing OAuth 1.0a integration and must keep your current codebase by retro fitting OAuth 2.0 and Xero tenant id headers.

    您具有现有的OAuth 1.0a集成,并且必须通过重新装配OAuth 2.0和Xero租户ID标头来保留当前代码库。
  2. You are working with WorkflowMax or Xero Practice Manager APIs that only return XML (our SDKs only handle JSON requests and responses).

    您正在使用仅返回XML(我们的SDK仅处理JSON请求和响应)的WorkflowMax或Xero Practice Manager API。
  3. You are working with APIs that are not currently supported in the SDK. At this time, NZ Payroll and Files are not supported, but will in the future.

    您正在使用SDK当前不支持的API。 目前不支持NZ Payroll和Files,但将来会支持。
  4. You prefer to roll your own solution or face some other constraint that prevents the use of an official SDK.

    您更喜欢推出自己的解决方案,或者遇到一些其他限制,从而无法使用正式的SDK。

Note: PHP developers who want to use our SDK should check out xero-php-oauth2.

注意:想要使用我们的SDKPHP开发人员应该签出 xero-php-oauth2

哪个OAuth 2客户端? (Which OAuth 2 client?)

There are many OAuth 2.0 clients for PHP but we found the PHP league oauth2-client easy to use.

有许多用于PHP的OAuth 2.0客户端,但是我们发现PHP联盟oauth2-client易于使用。

Today’s example code loads the oauth2-client library with composer. The oauth2-client handles our OAuth flow, and is used to retrieve a list of Xero tenants (and their tenant ids) in order to access Xero API endpoints.

今天的示例代码使用composer加载了oauth2-client库。 oauth2-client处理我们的OAuth流,并用于检索Xero租户列表(及其租户ID)以访问Xero API端点。

You can download the complete code shown in this post at php-oauth2-example.

您可以从php-oauth2-example下载此文章中显示的完整代码。

今天的先决条件 (Prerequisites for today)

  • A local server running PHP 5.6 or higher (i.e. MAMP)

    运行PHP 5.6或更高版本的本地服务器(即MAMP )

  • Composer: dependency manager for PHP installed

    Composer :已安装PHP的依赖项管理器

启动本地服务器 (Start your local server)

I’m using MAMP which has an htdocs folder as it’s webroot.

我正在使用具有htdocs文件夹的MAMP,因为它是webroot。

设置您的项目 (Setup your project)

Open up your terminal and navigate to the webroot folder (i.e. htdocs)

打开终端并导航到webroot文件夹(即htdocs)

cd /Applications/MAMP/htdocs

cd / Applications / MAMP / htdocs

Make a new folder for our project

为我们的项目新建一个文件夹

mkdir php-oauth2-example

mkdir php-oauth2-example

Change into our new folder

切换到我们的新文件夹

cd php-oauth2-example

cd php-oauth2-example

Create your composer.json file

创建您的composer.json文件

composer init

作曲家初始化

I just hit enter to accept the default answers to all the questions and when it asks about adding dependencies interactively say “no”. Do you confirm generation? Answer ‘yes’.

我只是按Enter接受所有问题的默认答案,当它询问以交互方式添加依赖项时,说“否”。 你确认世代吗? 回答“是”。

You’ve initialized your composer.json file. Let’s install the oauth2-client. In the terminal enter the following command to add the oauth2-client to your composer.json file.

您已经初始化了composer.json文件。 让我们安装oauth2-client。 在终端中,输入以下命令以将oauth2-client添加到您的composer.json文件。

composer require league/oauth2-client

作曲家需要联赛/ oauth2-client

Open the composer.json file and you should see “league/oauth2-client” under require.

打开composer.json文件,您将在require下看到“ league / oauth2-client”。

Your folder should look like this.

您的文件夹应如下所示。

Image for post

获取您的API密钥(客户端ID和机密) (Get your API keys (client id & secret))

If you don’t have a Xero user account, you can create one for free. Once you’ve activated your user account and enabled the Demo company.

如果您没有Xero用户帐户,则可以免费创建一个 。 激活用户帐户并启用演示公司后

  • Login to Xero developer portal and click “New app”.

    登录到Xero开发人员门户 ,然后单击“新应用”。

  • Enter your app name, company url, privacy policy url, and redirect URI (i.e. http://localhost:8888/php-oauth2-example/index.php).

    输入您的应用名称,公司网址,隐私政策网址和重定向URI(即http:// localhost:8888 / php-oauth2-example / index.php)。
  • Agree to the terms and conditions and click “Create App”.

    同意条款和条件,然后单击“创建应用”。
  • Click the “Generate a secret” button.

    点击“生成秘密”按钮。
  • Copy and save your client id and client secret for use later.

    复制并保存您的客户ID和客户机密,以备后用。

  • Click the “Save” button. Your secret is now hidden.

    点击“保存”按钮。 您的秘密现已隐藏。

让我们写一些代码。 (Let’s write some code.)

In our project folder, create a new file and name it index.php.

在我们的项目文件夹中, 创建一个新文件并将其命名为index.php。

第1步-配置OAuth 2.0客户端 (Step 1 — configure your OAuth 2.0 client)

On line 2, we load our dependencies, including the oauth2-client.

在第2行,我们加载了依赖项,包括oauth2-client。

On line 4, we start a session, so we can save our “state” value and compare it to the state returned by Xero when redirected back to our application. This check prevents CSRF (cross site request forgery) attacks.

在第4行,我们开始一个会话,因此我们可以保存“状态”值,并将其与Xero在重定向回我们的应用程序时返回的状态进行比较。 此检查可防止CSRF(跨站点请求伪造)攻击。

On line 6–8 we set our $clientId, $clientSecret and $redirectUri to match our Xero OAuth 2.0 application we created. Once those are in place, we can initialize the $provider on line 10–17.

在第6-8行,我们设置$ clientId,$ clientSecret和$ redirectUri以匹配我们创建的Xero OAuth 2.0应用程序。 一旦这些就绪,我们就可以在第10-17行初始化$ provider。

Copy and paste the following code.

复制并粘贴以下代码。

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


session_start();


$clientId = '__YOUR_CLIENT_ID__';
$clientSecret = '__YOUR_CLIENT_SECRET__';
$redirectUri = 'http://localhost:8888/php-oauth2-example/index.php';


$provider = new \League\OAuth2\Client\Provider\GenericProvider([
    'clientId'                => $clientId,   
    'clientSecret'            => $clientSecret,
    'redirectUri'             => $redirectUri,
    'urlAuthorize'            => 'https://login.xero.com/identity/connect/authorize',
    'urlAccessToken'          => 'https://identity.xero.com/connect/token',
    'urlResourceOwnerDetails' => 'https://api.xero.com/api.xro/2.0/Invoices'
]);


?>


<html>
<head>
	<title>php oauth2 example</title>
    <style>
        textarea { border:1px solid #999999;  width:75%; height: 75%;  margin:5px 0; padding:3px;  }
    </style>
</head>
<body>
<h3>Success!</h3>
</body>
</html>

Swap in your client id, client secret and the redirectURI set at the Xero developer portal.

交换在Xero开发人员门户上设置的客户端ID,客户端密钥和redirectURI。

Navigate your browser to load index.php (i.e. http://localhost:8888/php-oauth2-example/). You should see a success message.

浏览浏览器以加载index.php(即http:// localhost:8888 / php-oauth2-example / )。 您应该看到一条成功消息。

第2步-生成授权网址 (Step 2 — generate an authorization url)

Let’s look at the new code we’ve added.

让我们看看我们添加的新代码。

On line 20, we check if a query string param named “code” exists on our URL. If not, let’s execute the code inside our if statement.

在第20行,我们检查URL上是否存在名为“ code”的查询字符串参数。 如果没有,让我们在if语句中执行代码。

One line 22, we declare the $options array to hold our scopes. Scope define the resources our app will access through Xero’s API. Find out more about the scopes available and their corresponding endpoints.

在第22行,我们声明$ options数组来保存我们的范围。 范围定义了我们的应用程序将通过Xero的API访问的资源。 查找有关可用范围及其相应端点的更多信息。

On line 28, use the $provider object to generate an authorization URL.

在第28行,使用$ provider对象生成授权URL。

On line 31, before we redirect, save our state in a session variable.

在第31行上,在重定向之前,请将状态保存在会话变量中。

One line 33, display our authorization url on the screen.

一行33,在屏幕上显示我们的授权URL。

Update index.php. Copy and paste the following code.

更新index.php。 复制并粘贴以下代码。

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


session_start();


$clientId = '__YOUR_CLIENT_ID__';
$clientSecret = '__YOUR_CLIENT_SECRET__';
$redirectUri = 'http://localhost:8888/php-oauth2-example/index.php';


$provider = new \League\OAuth2\Client\Provider\GenericProvider([
    'clientId'                => $clientId,   
    'clientSecret'            => $clientSecret,
    'redirectUri'             => $redirectUri,
    'urlAuthorize'            => 'https://login.xero.com/identity/connect/authorize',
    'urlAccessToken'          => 'https://identity.xero.com/connect/token',
    'urlResourceOwnerDetails' => 'https://api.xero.com/api.xro/2.0/Invoices'
]);


// If we don't have an authorization code then get one
if (!isset($_GET['code'])) {


    $options = [
    	'scope' => ['openid email profile offline_access accounting.transactions accounting.settings']
    ];


    // 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($options);


    // Get the state generated for you and store it to the session.
    $_SESSION['oauth2state'] = $provider->getState();


    echo($authorizationUrl);


    exit();
} 


?>


<html>
<head>
	<title>php oauth2 example</title>
    <style>
        textarea { border:1px solid #999999;  width:75%; height: 75%;  margin:5px 0; padding:3px;  }
    </style>
</head>
<body>
<h3>Success!</h3>
</body>
</html>

Swap in your client id, client secret and the redirectURI set at the Xero developer portal.

交换在Xero开发人员门户上设置的客户端ID,客户端密钥和redirectURI。

Refresh your browser to execute this updated code and you should see your authorization url displayed on screen. It will look something like this.

刷新浏览器以执行此更新的代码,您应该在屏幕上看到授权URL。 它看起来像这样。

https://login.xero.com/identity/connect/authorize?scope=openid%20email%20profile%20offline_access%20accounting.transactions%20accounting.settings&state=1442d89e5abdfd40ae883ca818605bfa&response_type=code&approval_prompt=auto&redirect_uri=http%3A%2F%2Flocalhost%3A8888%2Fphp-oauth2-example%2Findex.php&client_id=E2B33204DE2643AF929928372DC2

https://login.xero.com/identity/connect/authorize?scope=openid%20email%20profile%20offline_access%20accounting.transactions%20accounting.settings&state=1442d89e5abdfd40ae883ca818605bfa&response_type=code&approval_prompt=auto&redirect_%2%uri 2Fphp-oauth2-example%2Findex.php&client_id = E2B33204DE2643AF929928372DC2

第3步-执行OAuth 2.0流程 (Step 3 — execute the OAuth 2.0 flow)

Let’s get our access token.

让我们获取访问令牌。

On line 35, forward the user to Xero to login and grant our app access. Once complete, the user is redirected back to our application.

在第35行,将用户转发到Xero登录并授予我们的应用访问权限。 完成后,用户将被重定向回我们的应用程序。

One line 38, if a ‘code’ parameter exists but the state parameter is empty or doesn’t match our saved oauth2state variable, we execute the elseif statement to and display an Invalid state message on line 40.

在第38行,如果存在“ code”参数,但state参数为空或与我们保存的oauth2state变量不匹配,我们将执行elseif语句并在第40行显示无效状态消息。

Otherwise, we execute line 43 else statement.

否则,我们执行第43行else语句。

One lines 47–49, we swap our code for an access token.

第47-49行,我们将代码交换为访问令牌。

On lines 53–59, we use the $provider and getAuthenticatedRequest method to perform a GET on the https://api.xero.com/connections endpoint passing in our $accessToken->getToken() and $options arguments. This returns an array of tenants so we know which organisation are associated with our access token.

在第53–59行,我们使用$ provider和getAuthenticatedRequest方法在https://api.xero.com/connections端点上执行GET,并传递我们的$ accessToken-> getToken()和$ options参数。 这将返回一组租户,因此我们知道哪个组织与我们的访问令牌相关联。

On line 61, we pass the $connectionsResponse object to the getParsedResponse method on the $provider object to get an array of Xero tenants and their IDs.

在第61行,我们将$ connectionsResponse对象传递给$ provider对象上的getParsedResponse方法,以获取Xero租户及其ID的数组。

Update index.php. Copy and paste the following code.

更新index.php。 复制并粘贴以下代码。

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


session_start();


$clientId = '__YOUR_CLIENT_ID__';
$clientSecret = '__YOUR_CLIENT_SECRET__';
$redirectUri = 'http://localhost:8888/php-oauth2-example/index.php';


$provider = new \League\OAuth2\Client\Provider\GenericProvider([
    'clientId'                => $clientId,   
    'clientSecret'            => $clientSecret,
    'redirectUri'             => $redirectUri,
    'urlAuthorize'            => 'https://login.xero.com/identity/connect/authorize',
    'urlAccessToken'          => 'https://identity.xero.com/connect/token',
    'urlResourceOwnerDetails' => 'https://api.xero.com/api.xro/2.0/Invoices'
]);


// If we don't have an authorization code then get one
if (!isset($_GET['code'])) {


    $options = [
    	'scope' => ['openid email profile offline_access accounting.transactions accounting.settings']
    ];


    // 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($options);


    // Get the state generated for you and store it to the session.
    $_SESSION['oauth2state'] = $provider->getState();


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


// Check given state against previously stored one to mitigate CSRF attack
} elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) {
    unset($_SESSION['oauth2state']);
    exit('Invalid state');


// Redirect back from Xero with code in query string param
} else {


    try {
        // Try to get an access token using the authorization code grant.
        $accessToken = $provider->getAccessToken('authorization_code', [
            'code' => $_GET['code']
        ]);


        // We have an access token, which we may use in authenticated requests 
        // Retrieve the array of connected orgs and their tenant ids.      
        $options['headers']['Accept'] = 'application/json';
        $connectionsResponse = $provider->getAuthenticatedRequest(
            'GET',
            'https://api.xero.com/Connections',
            $accessToken->getToken(),
            $options
        );


        $xeroTenantIdArray = $provider->getParsedResponse($connectionsResponse);
        
        echo "<h1>Congrats</h1>";
        echo "access token: " . $accessToken->getToken() . "<hr>";
        echo "refresh token: " . $accessToken->getRefreshToken() . "<hr>";
        echo "xero tenant id: " . $xeroTenantIdArray[0]['tenantId'] . "<hr>";


    } catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) {
        // Failed to get the access token or user details.
        exit($e->getMessage());
    }
}


?>


<html>
<head>
	<title>php oauth2 example</title>
    <style>
        textarea { border:1px solid #999999;  width:75%; height: 75%;  margin:5px 0; padding:3px;  }
    </style>
</head>
<body>
<h3>Success!</h3>
</body>
</html>

Swap in your client id, client secret and the redirectURI set at the Xero developer portal.

交换在Xero开发人员门户上设置的客户端ID,客户端密钥和redirectURI。

Refresh your browser to execute this updated code and you should go through the OAuth flow and return back to your application. It will look something like this.

刷新您的浏览器以执行此更新的代码,您应该遍历OAuth流程并返回到您的应用程序。 它看起来像这样。

Image for post

第4步-获取组织详细信息 (Step 4 — get organisation details)

We now have all the pieces necessary to make an authenticated request.

现在,我们拥有了进行身份验证请求所需的所有步骤。

On line 72 -73, we set the ‘xero-tenant-id’ header and the ‘accept’ header. This tells Xero’s API which tenant we are working with and how to format the data returned.

在第72 -73行,我们设置了'xero-tenant-id'标头和'accept'标头。 这告诉Xero的API我们正在使用哪个租户,以及如何格式化返回的数据。

On line 75–80, we pass in the method (GET, POST, PUT, etc), the resource url , access token and options.

在第75–80行,我们传入方法(GET,POST,PUT等),资源url,访问令牌和选项。

Update index.php. Copy and paste the following code.

更新index.php。 复制并粘贴以下代码。

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


session_start();


$clientId = '__YOUR_CLIENT_ID__';
$clientSecret = '__YOUR_CLIENT_SECRET__';
$redirectUri = 'http://localhost:8888/php-oauth2-example/index.php';


$provider = new \League\OAuth2\Client\Provider\GenericProvider([
    'clientId'                => $clientId,   
    'clientSecret'            => $clientSecret,
    'redirectUri'             => $redirectUri,
    'urlAuthorize'            => 'https://login.xero.com/identity/connect/authorize',
    'urlAccessToken'          => 'https://identity.xero.com/connect/token',
    'urlResourceOwnerDetails' => 'https://api.xero.com/api.xro/2.0/Invoices'
]);


// If we don't have an authorization code then get one
if (!isset($_GET['code'])) {


    $options = [
    	'scope' => ['openid email profile offline_access accounting.transactions accounting.settings']
    ];


    // 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($options);


    // Get the state generated for you and store it to the session.
    $_SESSION['oauth2state'] = $provider->getState();


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


// Check given state against previously stored one to mitigate CSRF attack
} elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) {
    unset($_SESSION['oauth2state']);
    exit('Invalid state');


// Redirect back from Xero with code in query string param
} else {


    try {
        // Try to get an access token using the authorization code grant.
        $accessToken = $provider->getAccessToken('authorization_code', [
            'code' => $_GET['code']
        ]);


        // We have an access token, which we may use in authenticated requests 
        // Retrieve the array of connected orgs and their tenant ids.      
        $options['headers']['Accept'] = 'application/json';
        $connectionsResponse = $provider->getAuthenticatedRequest(
            'GET',
            'https://api.xero.com/Connections',
            $accessToken->getToken(),
            $options
        );


        $xeroTenantIdArray = $provider->getParsedResponse($connectionsResponse);
        
        echo "<h1>Congrats</h1>";
        echo "access token: " . $accessToken->getToken() . "<hr>";
        echo "refresh token: " . $accessToken->getRefreshToken() . "<hr>";
        echo "xero tenant id: " . $xeroTenantIdArray[0]['tenantId'] . "<hr>";


        // The provider provides a way to get an authenticated API request for
        // the service, using the access token; 
        // the xero-tentant-id header is required
        // the accept header can be either 'application/json' or 'application/xml'
        $options['headers']['xero-tenant-id'] = $xeroTenantIdArray[0]['tenantId'];
	$options['headers']['Accept'] = 'application/json';        
        
        $request = $provider->getAuthenticatedRequest(
            'GET',
            'https://api.xero.com/api.xro/2.0/Organisation',
            $accessToken,
            $options
        );
        
	echo 'Organisation details:<br><textarea width: "300px"  height: 150px; row="50" cols="40">';
        var_export($provider->getParsedResponse($request));
        echo '</textarea>';
    } catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) {
        // Failed to get the access token or user details.
        exit($e->getMessage());
    }
}


?>


<html>
<head>
	<title>php oauth2 example</title>
    <style>
        textarea { border:1px solid #999999;  width:75%; height: 75%;  margin:5px 0; padding:3px;  }
    </style>
</head>
<body>
<h3>Success!</h3>
</body>
</html>

Swap in your client id, client secret and the redirectURI set at the Xero developer portal.

交换在Xero开发人员门户上设置的客户端ID,客户端密钥和redirectURI。

Refresh your browser to execute this updated code and see your organisation details displayed.

刷新浏览器以执行此更新的代码,并查看显示的组织详细信息。

Note: index.php is a very basic script meant to illustrate the OAuth 2.0 flow with minimal code. If you hit refresh on your browser after completing the redirect, you will see the Invalid state message. This is because you’ve already exchanged your code for an access token and can not use the code returned by Xero a 2nd time.

注意:index.php是一个非常基本的脚本,旨在用最少的代码说明OAuth 2.0流程。 如果您在完成重定向后在浏览器上单击“刷新”,则会看到“无效状态”消息。 这是因为您已经将代码替换为访问令牌,并且无法第二次使用Xero返回的代码。

As a bonus, if you pass the offline_access scope a refresh token is returned. After 30 minutes your access token will expire, but you use the $provider and refresh token to obtain a new access token.

另外,如果您通过offline_access范围,则返回刷新令牌。 30分钟后,您的访问令牌将过期,但是您可以使用$ provider和refresh令牌来获取新的访问令牌。

$newAccessToken = $provider->getAccessToken('refresh_token', [
    'refresh_token' => $accessToken>getRefreshToken()
]);

That’s it! OAuth 2.0 for PHP in 103 lines of code. Let us know how you are getting on and happy coding!

而已! 适用于PHP的OAuth 2.0包含103行代码。 让我们知道您过得如何,并祝您编程愉快!

Over 2 million small businesses, and their advisors are looking for the best cloud apps that integrate with Xero. Partner with us, and we’ll make sure they find yours.

超过200万的小型企业及其顾问正在寻找与Xero集成的最佳云应用程序。 与我们合作 ,我们将确保他们找到您的。

翻译自: https://devblog.xero.com/use-php-to-connect-with-xero-31945bccd037

xero 软件学习

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值