tan-tan-kanarek / github-php-client

MIT License
184 stars 120 forks source link

Value/interest in an approach to Oauth via web application flow? #75

Closed djplaner closed 8 years ago

djplaner commented 9 years ago

G'day,

Problem

My aim in using this client has been to use it in a web application. The problem is that I don't believe that the client supports GitHub Oauth via web application flow

Possible solution

I've developed a possible solution by combining this client with this PHP OAuth wrapper. The code below is for a simple web application that has the combination working.

To get this working has required some changes to GitHubClient base.

Relevant questions are

<?php

// Combine PHP-OAuth2 and GitHubClient to get details of authenticated user via Oauth web application flow

require('PHP-OAuth2/Client.php');
require('PHP-OAuth2/GrantType/IGrantType.php');
require('PHP-OAuth2/GrantType/AuthorizationCode.php');

require_once( __DIR__ . '/client/client/GitHubClient.php' );

// GitHub client details - need to register here https://github.com/settings/applications/new
// to get values for your script
const CLIENT_ID     = '?? replace with your value ??';
const CLIENT_SECRET = '?? replace with your value??';

// redirect URI for app - replace with URI for where you put this script
const REDIRECT_URI           = 'http://localhost:8080/oauth_combine.php';

// GitHub Oauth URLs
const AUTHORIZATION_ENDPOINT = 'https://github.com/login/oauth/authorize';
const TOKEN_ENDPOINT         = 'https://github.com/login/oauth/access_token';

// Generate a unique state variable 
$address=1530;
$STATE= hash('sha256', microtime(TRUE).rand().$address);

// the oauth client
$client = new OAuth2\Client(CLIENT_ID, CLIENT_SECRET);

if (!isset($_GET['code'])) {
    // if haven't got a code 
    // Send user to github oauth login

    // PHP-OAuth2 doesn't know about the extras for github
    $EXTRAS = Array( 'state' => $STATE, 'scope' => "user" );
    $auth_url = $client->getAuthenticationUrl(AUTHORIZATION_ENDPOINT,
                                                REDIRECT_URI, $EXTRAS);
    header('Location: ' . $auth_url);
    die('Redirect');
} else {
    // Got the temp code, need to exchange it for a token so we can get cracking

    $params = array('code' => $_GET['code'], 'redirect_uri' => REDIRECT_URI);
    $EXTRAS = Array( 'state' => $_GET['state'] );
    $response = $client->getAccessToken(TOKEN_ENDPOINT, 'authorization_code',
                                        $params, $EXTRAS);

    if ( $response['code'] != 200 ) {
        // oh dear, that failed
        print "<h3> Response was " . $response['code'] . "</h3>";
        die;
    }

    // got a 200 response = success?, parse the response and try to get token
    parse_str($response['result'], $info);

    if ( array_key_exists( 'access_token', $info ) ) {
        print "<h1>Got access token " . $info['access_token'] . "</h1>";

        // hand the token over to GitHubClient to start doing the query
        $oauth_token = $info['access_token'];
        $client = new GitHubClient();
        // The following two methods are new additions
        $client->setAuthType( 'Oauth' );
        $client->setOauthToken( $oauth_token );

        $response = $client->users->getTheAuthenticatedUser();

        // just dump the output
        var_dump( $response );

        // the following only works if a change is made to 
        // services/GitHubUsers.php
        print "<h3>Show user details</h3>";
        print "<ul> <li> Name: " . $response->getName() . "</li>" .
                 "<li> Email: " . $response->getEmail() . "</li></ul> ";
    } else {
         print "<h1> FAILURE - no token </h1>";
         print_r( $info );
    }
}
tan-tan-kanarek commented 9 years ago

Hi David, I designed this library for scripts and server side asynchronous operation, but just like you, there are many that find it useful for web applications as well, and many of them are also interested in OAuth2. Pull-request would be great, although I would try to avoid UI components in the code and offer the HTML UI directives and apache (or other web server) directives such as header, outside the code as examples.

Looking forward for you pull-request. T.

stefanomartinengo commented 3 years ago

Awesome. This helped me with my problem today. Thanks guys!