身份验证仅持续45秒

时间:2013-11-01 20:27:44

标签: perl oauth intuit-partner-platform quickbooks-online

我正在尝试开发一个应用程序,使用Perl在Quickbooks Online中创建发票。我可以使用OAuth进行身份验证(使用Net :: OAuth :: Simple),我可以通过回调成功接收OAuth令牌和机密。但是,如果我的连接空闲45秒,下次我发出请求时,会收到错误“401 Unauthorized”。

如何让我的连接持续时间超过45秒?

#!/usr/bin/perl

use strict;
use warnings;

package QuickbooksSketch;

use English qw/-no_match_vars/;
use Carp qw/carp croak/;
use Readonly;
use base qw{Net::OAuth::Simple};
use URI;

Readonly my $APP_TOKEN => q{REDACTED};
Readonly my $CONSUMER_KEY => q{REDACTED};
Readonly my $CONSUMER_SECRET => q{REDACTED};
Readonly my $QBO_URLS => {
    'request_token_url' => 'https://oauth.intuit.com/oauth/v1/get_request_token',
    'access_token_url'  => 'https://oauth.intuit.com/oauth/v1/get_access_token',
    'authorization_url' => 'https://appcenter.intuit.com/Connect/Begin',
};
Readonly my $QUERY_URL_BASE => 'https://qb.sbfinance.intuit.com/v3/company';
Readonly my $PROTOCOL_VERSION => q{1.0a};
Readonly my $CALLBACK_URL => q{http://localhost/callback};
Readonly my $REALM_ID => 12345;

Readonly my $GOOD_URI => q{https://appcenter.intuit.com/api/v1/Account/AppMenu};
Readonly my $QUERY_URI => q{https://qb.sbfinance.intuit.com/v3/company/828655235/query?query=select * from Customer};
Readonly my $RECONNECT_URI => q{https://appcenter.intuit.com/api/v1/Connection/Reconnect};

sub new {
    my ($class, $args) = @_;
    my $self = $class->SUPER::new(
        'tokens' => {
            'consumer_key' => $CONSUMER_KEY,
            'consumer_secret' => $CONSUMER_SECRET,
        },
        'urls' => $QBO_URLS,
    );
    $self->{'realm_id'} = $args->{'realm_id'};
    return $self;
}

sub get_authorization_url {
    my ($self, %params) = @_;
    $params{'callback'} ||= qq{http://$CALLBACK_URL/};
    return $self->SUPER::get_authorization_url(%params);
}

package main;

use English qw/-no_match_vars/;
use Carp qw/carp croak/;
use Getopt::Long;
use POSIX qw/strftime/;
use FindBin qw($Bin);
use File::Slurp qw(read_file);
use Readonly;
use Socket;
use IO::Handle;
use Data::Dumper;

sub main {
    my $qb = QuickbooksSketch->new();
    my ($access_token, $access_token_secret) = read_access_tokens($REALM_ID);

    $qb->access_token($access_token);
    $qb->access_token_secret($access_token_secret);

    while (!$qb->authorized) {
        authorize($qb);
    }

    my $response1 = $qb->make_restricted_request($GOOD_URI, 'GET');
    if ($response1->content =~ /This app is no longer connected/) {
        print qq{No longer connected, yadda yadda yadda\n};
    }

    # This works IFF the access tokens are less than 45 seconds old
    my $response2;
    $response2 = eval {
        $qb->make_restricted_request($QUERY_URI, 'GET', 'query' => q{select * from Customer}, 'Headers' => ['Accept' => 'application/json']);
    } or die qq{$EVAL_ERROR\n};
    print $response2->content, qq{\n};

    # This is giving me "Token Refresh Window Out of Bounds"
    my $response3 = eval {
        $qb->make_restricted_request($RECONNECT_URI, 'GET', 'Headers' => ['Accept' => 'application/json']);
    } or die qq{Caught exception in reconnect URI: $EVAL_ERROR\n};

    print $response3->content, qq{\n};
}

sub authorize {
    my $qb = shift;

    my ($read_sock, $write_sock);
    socketpair($read_sock, $write_sock, AF_UNIX, SOCK_STREAM, PF_UNSPEC) or die "socketpair: $OS_ERROR";

# callback sends data over socket

    my $auth_url = $qb->get_authorization_url;
    print STDERR qq/Authorization credentials not present or expired.  Please reauthorize at $auth_url\n/;

    my $auth_data = {};

    while( my $message = <$read_sock> ) {
        chomp $message;
        last if ($message eq 'END');
        my ($key, $val) = split /\s*:\s*/, $message, 2;
        $auth_data->{$key} = $val;
    }
    shutdown $read_sock, 2;
    shutdown $write_sock, 2;

    my $verifier = $auth_data->{'oauth_verifier'};
    if (!$verifier) {
        die qq{OAuth authentication failed\n};
    }
    print qq{Set verifier to $verifier\n};
    $qb->verifier($verifier);
    my ($access_token, $access_token_secret) = $qb->request_access_token;

    store_access_tokens($auth_data->{'realmId'}, $access_token, $access_token_secret);
    $qb->access_token($access_token);
    $qb->access_token_secret($access_token_secret);
# shut down handler
}

0 个答案:

没有答案