-
Notifications
You must be signed in to change notification settings - Fork 0
Reference OAuth2
Imported from Trac page
docs_oauth2. Source: https://genapp.rocks/wiki/wiki/docs_oauth2. Review age and examples before treating as current.
The OAuth 2.0 authorization framework enables a third-party application (Google,Facebook etc.) to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service, or by allowing the third-party application to obtain access on its own behalf.
Irrespective of the third-party application used, at a high level there are several steps:
-
Registering application to obtain OAuth2 credentials of the third-party, such as client ID and client secret.
-
Obtaining authorization to access third-party's API (OAuth2 server)
-
User authentication on OAuth2 server
-
Redirecting back to user application
In this section we will provide some specific examples of authentication flow employing different third-party applications. We start with Google. More examples will be provided later.
Detailed documentation is available at https://developers.google.com/identity/protocols/OAuth2
Below is a compete example of user authentication using Google's PHP API library and jQuery:
-
Obtain web application credentials for your project. Compete the following steps:
- Go to Google API console. Create a project.
- Create your OAuth 2.0 credentials by clicking 'Create new Client ID' under the 'OAuth Client ID' heading. Choose 'Web Application'.
- For 'Authorized redirect URIs' put the path in your application that user will be redirected to after authentication via Google. For the example provided below, it should be a path to oath2.php file.
- Download user credentials for you project by clicking 'Download JSON' in Google API console and save it to the place when oath2.php resides.
- Rename a saved .json to 'client_secrets.json'.
-
install the Google API Client Library for PHP using Composer:
composer require google/apiclient:^2.0
- create the file oauth2.php with the following content
<?php
require_once __DIR__.'/vendor/autoload.php';
session_start();
$client = new Google_Client();
$client->setAuthConfig('client_secrets.json'); // 'client_secrets.json' is downloaded from Google's API console for your project
$client->addScope(Google_Service_Oauth2::USERINFO_PROFILE);
$client->addScope(Google_Service_Oauth2::USERINFO_EMAIL);
$service = new Google_Service_Oauth2($client); // you can create different services to access user's information, look Google's documentation
if (! isset($_GET['code'])) {
$auth_url = $client->createAuthUrl();
//header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
echo filter_var($auth_url, FILTER_SANITIZE_URL);
}
else {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
$user = $service->userinfo->get();
$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . "/?weloggedin=1&email=$user->email"; // Here we pass user's email to the redirect URL
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
exit;
}
- on the client side, add the following jQuery code:
$( "#login_google" ).click( function() // id of the button associated with login via Google
{
my_google_call();
});
function my_google_call() {
$.ajax({
type: 'GET',
datatype: "html",
url:'oauth2.php', // location of the above .php code
})
.done( function(data)
{
window.location.href = data;
})
.fail ( function()
{
messagebox( { icon: "toast.png",
text: "There was an error!",
buttons : [ { id : "ok", label : "OK" } ] });
return;
});
}
// PARSE URL ARGUMENTS
urlparams = function( sParam ) {
var sURLVariables = window.location.search.substring(1).split('&');
for (var i = 0; i < sURLVariables.length; i++) {
var sParameterName = sURLVariables[i].split('=');
if (sParameterName[0] == sParam) {
return sParameterName[1];
}
}
}
if (urlparams("weloggedin")){
messagebox( { icon: "toast.png",
text: ga.urlparams("email") ? ("We logged in, Email is: " + ga.urlparams("email")) : "We logged in, No Email",
buttons : [ { id : "ok", label : "OK" } ] });
}
window.history.replaceState({},"MyWebSite","/myweb/"); // clear URL from user's data [title and application are assumed to be 'MyWebSite' and 'myweb', respectively]
See documentaion at https://docs.globus.org/api/auth/developer-guide
-
To register application, compete the following steps:
- Navigate to https://developers.globus.org, click 'Register your App with Globus'
- Use your credentials to Log in [select organization from the drop down menu]
- Add a project
-
Create a oauth2.php file with the following content:
<?php
session_start();
$client_id = 'XXXX'; // from Globus's API console for your registered app
$client_secret = 'XXXXXXXXXX'; // from Globus's API console for your registered app
$redirect_uri = '/path/to/oauth2.php'; // the link your app will be redirected to after authorization (to this .php file)
$scope = 'openid+email+profile'; // scopes [to use https://auth.globus.org/v2/oauth2/userinfo endpoint]
$response_type = 'code';
if (! isset($_GET['code'])) {
$auth_url = "https://auth.globus.org/v2/oauth2/authorize?client_id=$client_id&redirect_uri=$redirect_uri&scope=$scope&response_type=$response_type";
//header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
echo filter_var($auth_url, FILTER_SANITIZE_URL);
}
else
{
$code = $_GET['code'];
/// Authorization /////////////////////////////////////////////////////
$url = 'https://auth.globus.org/v2/oauth2/token';
$sPD = array('grant_type' => 'authorization_code', 'redirect_uri' => $redirect_uri, 'code' => $code, 'client_id' => $client_id);
$options_post = array(
'http' => array(
'method' => 'POST',
'header' => array ('Content-type: application/x-www-form-urlencoded'
,'Authorization: Basic '. base64_encode("$client_id:$client_secret")
),
'content' => http_build_query($sPD)
)
);
$context = stream_context_create($options_post);
$result = file_get_contents($url, false, $context);
$res_json = json_decode($result, true);
//var_dump($result);
//echo "<br><br>";
//echo ($res_json['other_tokens']['0']['access_token']);
//////// Use access token to get Globus's user profile: v2/oauth2/userinfo endpoint /////////////////////////////////////////
$url_token = 'https://auth.globus.org/v2/oauth2/userinfo';
$options_use_token = array(
'http' => array(
'method' => 'POST',
'header' => array( 'Authorization: Bearer ' . $res_json['access_token'] )
)
);
$context_use_token = stream_context_create($options_use_token);
$result_use_token = file_get_contents($url_token, false, $context_use_token);
//echo "<br>";
//echo "<br>";
//var_dump ($result_use_token);
$res_json_use_token = json_decode($result_use_token, true);
$user_email = $res_json_use_token['email'];
$user_name = $res_json_use_token['name'];
$sub_id = $res_json_use_token['sub'];
///// Use access token to get user identities: v2/api/identities/<id> endpoint ////////////////////////////////////
$url_token_id = "https://auth.globus.org/v2/api/identities/" . "$sub_id";
$options_use_token_id = array(
'http' => array(
'method' => 'GET',
'header' => array( 'Authorization: Bearer ' . $res_json['access_token'] )
)
);
$context_use_token_id = stream_context_create($options_use_token_id);
$result_use_token_id = file_get_contents($url_token_id, false, $context_use_token_id);
//echo "<br>";
//echo "<br>";
//var_dump ($result_use_token_id);
$res_json_use_token_id = json_decode($result_use_token_id, true);
$user_username = $res_json_use_token_id['identity']['username'];
$user_username_split = explode("@", $user_username);
//echo ( $user_username_split[0] );
$redirect_uri = 'http://localhost/mywebtraning'. "/?weloggedinglobus=1&email=$user_email&name=$user_name&username=$user_username_split[0]";
//Pass user info into the redirect uri for further processing on the client side
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
- Comments on the oauth2.php code:
- As we do not use any off-the-shelf OAuth2 library (like in case with Google above), we provide variables defining $client_id, $client_secret etc.
- Scopes has to be provided in the format 'scope1+scope2+scope3+etc' - not as stated in https://docs.globus.org/api/auth/developer-guide (A space or comma separated list of scopes)
- Globus API endpoints:
- Authorization: https://auth.globus.org/v2/oauth2/token
- User Information: https://auth.globus.org/v2/oauth2/userinfo
- User Identities: https://auth.globus.org/v2/api/identities/, where is obtained from a request to https://auth.globus.org/v2/oauth2/userinfo, a content of 'sub' field
To enable Oauth2 authrization via Google and Globus API, the following sections have to be added to directives.json and appconfig.json files:
- directives.json
"usesplash" : "true"
,"register" : {
"globuslogin" : "true"
,"googlelogin" : "true"
}
- appconfig.json
"oauth2" : {
"globus" : {
"client_id" : "XXXX"
,"client_secret" : "XXXXXXXX"
}
,"google" : {
"client_id" : "XXXXXXXX"
,"client_secret" : "XXXXXXXXXXXX"
}
}
where 'client_id' and 'client_secret' are credentials of the application registered with Globus or Google.
When Oauth2 authorization via Google and Globus API is used, there may be a need to disable (hide) regular login/registration. To do so, just add the following line into appconfig.json or directives.json:
"hideregularlogin" : "true"
in appconfig.json the "only" key word is responsible for this:
"oauth2" : {
"only" : [xsede.org, ...],
"globus" : {
"client_id" : "XXXX"
,"client_secret" : "XXXXXXXX"
}
,"google" : {
"client_id" : "XXXXXXXX"
,"client_secret" : "XXXXXXXXXXXX"
}
}
in appconfig.json use "stripdomain" key word:
"oauth2" : {
"stripdomain" : "true",
"only" : [xsede.org, ...],
"globus" : {
"client_id" : "XXXX"
,"client_secret" : "XXXXXXXX"
}
,"google" : {
"client_id" : "XXXXXXXX"
,"client_secret" : "XXXXXXXXXXXX"
}
}
in appconfig.json, to specify https use "use_https" key word:
"oauth2" : {
"use_https" : "true",
"stripdomain" : "true",
"only" : [xsede.org, ...],
"globus" : {
"client_id" : "XXXX"
,"client_secret" : "XXXXXXXX"
}
,"google" : {
"client_id" : "XXXXXXXX"
,"client_secret" : "XXXXXXXXXXXX"
}
}
Otherwise, for http pages do not use "use_https".