Sample code for 30+ languages & platforms
Perl Requires Chilkat v10.1.2+

OAuth2 using an HTTP Proxy (for a Desktop Application)

See more OAuth2 Examples

Shows how to send OAuth2 communications through an HTTP proxy in a desktop application, using Microsoft Graph as an example. This method applies to all OAuth2 applications.

Chilkat Perl Downloads

Chilkat2 Perl
use strict;
use warnings;
use Chilkat2;

# This example requires the Chilkat API to have been previously unlocked.
# See Global Unlock Sample for sample code.

# To use an HTTP proxy with OAuth2, create a Chilkat socket object and specify the details.
my $socket = Chilkat2::Socket->new;
# Use your HTTP proxy server domain or IP address.
$socket->HttpProxyHostname('myproxyserver.com');
# Change this to the listening port of your HTTP proxy server (if necessary)
$socket->HttpProxyPort(808);
# Specify login/password if needed.
$socket->HttpProxyUsername('myProxyLogin');
$socket->HttpProxyPassword('myProxyPassword');
$socket->HttpProxyForHttp(1);

my $oauth2 = Chilkat2::OAuth2->new;

# We don't need to connect the socket beforehand.
# Just tell oauth2 to use the socket which has the HTTP proxy properties.
my $success = $oauth2->UseConnection($socket);

# This should be the port in the localhost callback URL for your app.
# The callback URL would look like "http://localhost:3017/" if the port number is 3017.
$oauth2->ListenPort(3017);

$oauth2->AuthorizationEndpoint('https://login.microsoftonline.com/common/oauth2/v2.0/authorize');
$oauth2->TokenEndpoint('https://login.microsoftonline.com/common/oauth2/v2.0/token');

# Replace these with actual values.
$oauth2->ClientId('MICROSOFT-GRAPH-CLIENT-ID');
# This is your app password:
$oauth2->ClientSecret('MICROSOFT-GRAPH-CLIENT-SECRET');

$oauth2->CodeChallenge(0);
# Provide a SPACE separated list of scopes.
# See https://developer.microsoft.com/en-us/graph/docs/authorization/permission_scopes

# Important: To get a refresh token in the final response, you have to ask for "offline_access" scope
$oauth2->Scope('openid profile offline_access user.readwrite mail.readwrite mail.send files.readwrite');

# Begin the OAuth2 Authorization code flow.  This returns a URL that should be loaded in a browser.
my $url = $oauth2->StartAuth();
if (!$oauth2->LastMethodSuccess) {
    print $oauth2->LastErrorText, "\n";
    exit;
}

print 'url = ', $url, "\n";

# Launch the default browser on the system and navigate to the url.
$success = $oauth2->LaunchBrowser($url);
if (!$success) {
    print $oauth2->LastErrorText, "\n";
    exit;
}

# Wait for the user to approve or deny authorization in the browser.
my $numMsWaited = 0;
while (($numMsWaited < 90000) && ($oauth2->AuthFlowState < 3)) {
    $oauth2->SleepMs(100);
    $numMsWaited = $numMsWaited + 100;
}

# If the browser does not respond within the specified time, AuthFlowState will be:
#
# 1: Waiting for Redirect - The OAuth2 background thread is waiting for the browser's redirect request.
# 2: Waiting for Final Response - The thread is awaiting the final access token response.
# In either case, cancel the background task initiated by StartAuth.

if ($oauth2->AuthFlowState < 3) {
    $oauth2->Cancel();
    print "No response from the browser!\n";
    exit;
}

# Check AuthFlowState to determine if authorization was granted, denied, or failed:
#
# 3: Success - OAuth2 flow completed, the background thread exited, and the successful response is in AccessTokenResponse.
# 4: Access Denied - OAuth2 flow completed, the background thread exited, and the error response is in AccessTokenResponse.
# 5: Failure - OAuth2 flow failed before completion, the background thread exited, and error details are in FailureInfo.

if ($oauth2->AuthFlowState == 5) {
    print "OAuth2 failed to complete.\n";
    print $oauth2->FailureInfo, "\n";
    exit;
}

if ($oauth2->AuthFlowState == 4) {
    print "OAuth2 authorization was denied.\n";
    print $oauth2->AccessTokenResponse, "\n";
    exit;
}

if ($oauth2->AuthFlowState != 3) {
    print 'Unexpected AuthFlowState:', $oauth2->AuthFlowState, "\n";
    exit;
}

print "OAuth2 authorization granted!\n";
print 'Access Token = ', $oauth2->AccessToken, "\n";

# Get the full JSON response:
my $json = Chilkat2::JsonObject->new;
$json->Load($oauth2->AccessTokenResponse);
$json->EmitCompact(0);

# The JSON response looks like this:

# {
#   "token_type": "Bearer",
#   "scope": "User.Read Mail.ReadWrite Mail.Send",
#   "expires_in": 3600,
#   "ext_expires_in": 0,
#   "access_token": "EwBAA8l6B...",
#   "refresh_token": "MCRMdbe...",
#   "id_token": "eyJ0eXA..."
# }

# If an "expires_on" member does not exist, then add the JSON member by
# getting the current system date/time and adding the "expires_in" seconds.
# This way we'll know when the token expires.
if (!$json->HasMember('expires_on')) {
    my $dtExpire = Chilkat2::DateTime->new;
    $dtExpire->SetFromCurrentSystemTime();
    $dtExpire->AddSeconds($json->IntOf('expires_in'));
    $json->AppendString('expires_on', $dtExpire->GetAsUnixTimeStr(0));
}

print $json->Emit(), "\n";

# Save the JSON to a file for future requests.
my $fac = Chilkat2::FileAccess->new;
$fac->WriteEntireTextFile('qa_data/tokens/microsoftGraph.json', $json->Emit(), 'utf-8', 0);