I am following the instructions here:
https://learn.microsoft.com/en-us/graph/auth-v2-user?view=graph-rest-1.0#3-get-a-token
I get the authorisation response and therefore the required code, but when I request the token I get a "HTTP/1.1 401 Unauthorized" response.
This is my code (not for production, just for me to get the flow/code right first):
<?php
/*
Auth
https://learn.microsoft.com/en-us/graph/auth-v2-user?view=graph-rest-1.0
*/
define("HOST", 'https://login.microsoftonline.com');
define("TENANT", 'common');
define("AUTH_ENDPOINT", HOST.'/'.TENANT.'/oauth2/v2.0/authorize');
define("TOKEN_ENDPOINT", HOST.'/'.TENANT.'/oauth2/v2.0/token');
define("CLIENT_ID", '<< FROM AZURE PORTAL >>');
define("CLIENT_SECRET", '<< FROM AZURE PORTAL >>');
define("ALL_SCOPES", rawurlencode('offline_access user.read mail.read'));
define("CALLBACK", rawurlencode('http://localhost:300/graph2/auth.php'));
// Build URL
$url = AUTH_ENDPOINT."?client_id=".CLIENT_ID;
$url .= "&response_type=code";
$url .= "&redirect_uri=".CALLBACK;
$url .= "&response_mode=query";
$url .= "&scope=".ALL_SCOPES;
echo "<a href=$url>$url</a>";
if (isset($_GET))
{
echo '<pre>';print_r($_GET);echo'</pre>';
if (isset($_GET['code']))
{
// Got authorisation code - now need token
$response = requestAccessTokenByVerifier($_GET['code']);
echo ">".$response;
}
}
function requestAccessTokenByVerifier($verifier)
{
return requestAccessToken(
array(
'client_id' => CLIENT_ID,
'redirect_uri' => CALLBACK,
'client_secret' => CLIENT_SECRET,
'code' => $verifier,
'grant_type' => 'authorization_code',
'scope' => ALL_SCOPES
)
);
}
function requestAccessToken($content)
{
$response = sendRequest(TOKEN_ENDPOINT, 'POST', $content);
if ($response !== false)
{
$authToken = json_decode($response);
if (!empty($authToken) && !empty($authToken->{ACCESSTOKEN})) return $authToken;
}
die("No access token");
return false;
}
function sendRequest($url, $method = 'GET', $data = array(), $headers = array('Content-Type: application/x-www-form-urlencoded'))
{
$context = stream_context_create(
array(
'http' => array(
'method' => $method,
'header' => $headers,
'content' => buildQueryString($data)
)
)
);
echo "URL: $url<br>";
echo '<pre>';print_r($data);echo '</pre>';
echo buildQueryString($data)."<br>";
$response = file_get_contents($url, false, $context);
echo '<pre>';var_dump($http_response_header);echo '</pre>';
return $response;
}
function buildQueryString($array)
{
$result = '';
foreach ($array as $k => $v)
{
if ($result == '') $prefix = ''; else $prefix = '&';
$result .= $prefix . $k . '=' . $v;
}
return $result;
}
?>
As you will see I've put a few basic diagnostics in there which show I am getting the code required successfully, but then not being able to get a token from the code.
Can anybody suggest what to try next, I wonder either from a debugging point of view or alternative approaches.
Thanks.
OK, after digging around I realised I'd made a stupid mistake, but just in case anybody else does the same - you need to use the client secret value not id!
I've deleted that client secret :)
Hope that helps somebody else bashing their head against a brick wall.
Related
Right after the registration process there is a link shown to set password:
http://website.de/main/complete/token/MTkyYTBiY2EyNWE2ZDYwOTdhN2U4NjJkMjZmYzYyNTA
The problem is I can't display this page to complete the registration process.
Does anyone have a clue why? I'm already looking since 2 hours for it...
Controller function:
public function complete()
{
$token = base64_decode($this->uri->segment(4));
$cleanToken = $this->security->xss_clean($token);
$user_info = $this->user_model->isTokenValid($cleanToken); //either false or array();
if(!$user_info){
$this->session->set_flashdata('flash_message', 'Token is invalid or expired');
redirect(base_url().'login');
}
$data = array(
'firstName'=> $user_info->first_name,
'email'=>$user_info->email,
'user_id'=>$user_info->id,
'token'=>$this->base64url_encode($token)
);
$this->form_validation->set_rules('password', 'Password', 'required|min_length[5]');
$this->form_validation->set_rules('passconf', 'Password Confirmation', 'required|matches[password]');
if ($this->form_validation->run() == FALSE) {
$this->load->view('header');
$this->load->view('complete', $data);
$this->load->view('footer');
}else{
$this->load->library('password');
$post = $this->input->post(NULL, TRUE);
$cleanPost = $this->security->xss_clean($post);
$hashed = $this->password->create_hash($cleanPost['password']);
$cleanPost['password'] = $hashed;
unset($cleanPost['passconf']);
$userInfo = $this->user_model->updateUserInfo($cleanPost);
if(!$userInfo){
$this->session->set_flashdata('flash_message', 'There was a problem updating your record');
redirect(base_url().'login');
}
unset($userInfo->password);
foreach($userInfo as $key=>$val){
$this->session->set_userdata($key, $val);
}
redirect(base_url());
}
}
public function register()
{
$this->form_validation->set_rules('firstname', 'First Name', 'required');
$this->form_validation->set_rules('lastname', 'Last Name', 'required');
$this->form_validation->set_rules('email', 'Email', 'required|valid_email');
if ($this->form_validation->run() == FALSE) {
$this->load->view('header');
$this->load->view('register');
$this->load->view('footer');
}else{
if($this->user_model->isDuplicate($this->input->post('email'))){
$this->session->set_flashdata('flash_message', 'User email already exists');
redirect(base_url().'login');
}else{
$clean = $this->security->xss_clean($this->input->post(NULL, TRUE));
$id = $this->user_model->insertUser($clean);
$token = $this->user_model->insertToken($id);
$qstring = $this->base64url_encode($token);
$url = base_url() . 'complete/token/' . $qstring;
$link = '' . $url . '';
$message = '';
$message .= '<strong>You have signed up with our website</strong><br>';
$message .= '<strong>Please click:</strong> ' . $link;
echo $message; //send this in email
exit;
};
}
}
Model functions:
public function insertToken($user_id)
{
$token = substr(sha1(rand()), 0, 30);
$date = date('Y-m-d');
$string = array(
'token'=> $token,
'user_id'=>$user_id,
'created'=>$date
);
$query = $this->db->insert_string('tokens',$string);
$this->db->query($query);
return $token . $user_id;
}
public function isTokenValid($token)
{
$tkn = substr($token,0,30);
$uid = substr($token,30);
$q = $this->db->get_where('tokens', array(
'tokens.token' => $tkn,
'tokens.user_id' => $uid), 1);
if($this->db->affected_rows() > 0){
$row = $q->row();
$created = $row->created;
$createdTS = strtotime($created);
$today = date('Y-m-d');
$todayTS = strtotime($today);
if($createdTS != $todayTS){
return false;
}
$user_info = $this->getUserInfo($row->user_id);
return $user_info;
}else{
return false;
}
}
what you want to do is, after user successfully registered, show him/her a url to complete the registration right?
As far as I understood the problem, you can do like this,
in your controller,
$message = '';
$message .= '<strong>You have signed up with our website</strong><br>';
$message .= '<strong>Please click:</strong> ' . $link;
$data = array(
'message' => $message
);
$this->load->view('header');
$this->load->view('complete', $data);
$this->load->view('footer');
And create a view called complete.php
<html>
<head>
<title></title>
</head>
<body>
<h1><?php echo $message;?></h1>
</body>
</html>
Adding Dynamic Data to the View - https://www.codeigniter.com/userguide2/general/views.html
Hel-lo! Need to retrieve GWT data (top pages, top queries, internal/external links, etc.). Wrote a php-script (based on this):
//"GetAccessCode.php" file
$OAuth = array(
'oauth_uri' => 'https://accounts.google.com/o/oauth2/auth',
'client_id' => 'here is my client id',
'client_secret' => 'here is my client secret',
'redirect_uri' => 'http://localhost/google/GetAccessCode.php',
'oauth_token_uri' => 'https://accounts.google.com/o/oauth2/token',
);
$token = array(
'access_token' => '',
'token_type' => '',
'expires_in' => '',
'refresh_token' => ''
);
$title = 'No Code';
$AuthCode = 'Null';
// see if error parameter exisits
$error = _get_url_param($_SERVER['REQUEST_URI'], 'error');
if ($error != NULL)
{ // this means the user denied api access to GWMTs
$title = $error;
}
else
{ // does the code parameter exist?
$AuthCode = _get_url_param($_SERVER['REQUEST_URI'], 'code');
if ($AuthCode == NULL)
{ // get authorization code
$OAuth_request = _formatOAuthReq($OAuth, "https://www.google.com/webmasters/tools/feeds/sites/"); //**WHAT URI NEED TO BE HERE?**
header('Location: ' . $OAuth_request);
exit; // the redirect will come back to this page and $code will have a value
}
else
{
$title = 'Got Authorization Code';
// now exchange Authorization code for access token and refresh token
$token_response = _get_auth_token($OAuth, $AuthCode);
$json_obj = json_decode($token_response);
$token['access_token'] = $json_obj->access_token;
$token['token_type'] = $json_obj->token_type;
$token['expires_in'] = $json_obj->expires_in;
$token['refresh_token'] = $json_obj->refresh_token;
$sites = _get_wmt_sites_feed($token);
echo $sites;
}
}
// Return the list of sites registered in your Google Webmaster Tools
function _get_wmt_sites_feed($access_tokens)
{
$post_string = "https://www.google.com/webmasters/tools/feeds/sites/"; //**WHAT URI NEED TO BE HERE?**
$post_string .= '?v=2';
$post_string .= '&oauth_token=' . $access_tokens['access_token'];
$response = file_get_contents($post_string);
return _parse_wmt_sites_response($response);
}
function _parse_wmt_sites_response($response)
{
$xml = simplexml_load_string($response);
$response = '<br />';
foreach ($xml->entry as $entry)
{
foreach ($entry->title as $title)
{
$response .= "<p>$title</p>";
}
}
return $response;
}
function _get_auth_token($params, $code)
{
$url = $params['oauth_token_uri'];
$fields = array(
'code' => $code,
'client_id' => $params['client_id'],
'client_secret' => $params['client_secret'],
'redirect_uri' => $params['redirect_uri'],
'grant_type' => 'authorization_code'
);
$response = _do_post($url, $fields);
return $response;
}
function _do_post($url, $fields)
{
$fields_string = '';
foreach ($fields as $key => $value)
{
$fields_string .= $key . '=' . $value . '&';
}
$fields_string = rtrim($fields_string, '&');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
function _formatOAuthReq($OAuthParams, $scope)
{
$uri = $OAuthParams['oauth_uri'];
$uri .= "?client_id=" . $OAuthParams['client_id'];
$uri .= "&redirect_uri=" . $OAuthParams['redirect_uri'];
$uri .= "&scope=" . $scope;
$uri .= "&response_type=code";
return $uri;
}
function _get_url_param($url, $name)
{
parse_str(parse_url($url, PHP_URL_QUERY), $params);
return isset($params[$name]) ? $params[$name] : null;
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><?= $title; ?></title>
</head>
<body>
<h1>OAuth2 Authorization Code</h1>
<p>Authorization Code: <?= $AuthCode; ?></p>
<p>access token: <?=$token['access_token'];?></p>
<p>expires in: <?=$token['expires_in'];?></p>
<p>refresh token: <?=$token['refresh_token'];?></p>
<p></p>
</body>
</html>
What URI need I to write in the code above instead of https:// www.google.com/webmasters/tools/feeds/sites/ to retrieve the desired data? In this nice code - https://github.com/eyecatchup/php-webmaster-tools-downloads - author uses https:// www.google.com/webmasters/tools/downloads-list?hl=en&siteUrl=http: //site.com/, but also he uses ClientLogin. I try to use this link in my script, but it generates mistakes, because, as I understand, this is not a right scope. So, what is right?
Also found this post here, it mentions about some Basic Authentication. I'm a beginner in Google API, please, tell, what do they mean?
I have a shopping site and I have to send username and password and some other data to the bank, so I have used curl for posting data .because it should be safe.
but my problem is when I post data with curl to the bank, page url dont change! I see banks result in my server page !!!
I need this posting data same as posting data in html page redirect too the url which has been determined !!
$data = array(
"MID" => "0113-19",
"RedirectURL" => $SERVER . "/shop/profile.php",
"Amount" => $sum,
"ResNum" => $ResNum,
"username" => "xxxx",
"password" => "1234");
//traverse array and prepare data for posting (key1=value1)
foreach ( $data as $key => $value) {
$data[] = $key . '=' . urlencode($value);
}
$post_string = implode ('&', $data);
$res = array();
$options = array(
CURLOPT_RETURNTRANSFER => true, // return web page
CURLOPT_POST => true, // return web page
CURLOPT_FOLLOWLOCATION => true, // follow redirects
CURLOPT_AUTOREFERER => false, // set referer on redirect
CURLOPT_CONNECTTIMEOUT => 120, // timeout on connect
CURLOPT_TIMEOUT => 120, // timeout on response
CURLOPT_MAXREDIRS => 10, // stop after 10 redirects
CURLOPT_POSTFIELDS => $post_string, // stop after 10 redirects
CURLOPT_SSL_VERIFYPEER => false , // stop after 10 redirects
CURLOPT_COOKIEJAR => "cookie.txt" , // stop after 10 redirects
CURLOPT_COOKIEFILE => "cookie.txt" , // stop after 10 redirects
CURLOPT_SSL_VERIFYPEER => false , // stop after 10 redirects
CURLOPT_USERAGENT => "Mozilla/5.0 (Windows; U;
Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1" // stop after 10 redirects
);
//////////////////////
$ch = curl_init( $url );
curl_setopt_array( $ch, $options );
$content = curl_exec( $ch );
$err = curl_errno( $ch );
$errmsg = curl_error( $ch );
$header = curl_getinfo( $ch );
curl_close( $ch );
Anyone know how I can tweak the settings in the Wordpress theme used in this site (http://www.ethnecity.church.ly/) to make the Twitter section (near the bottom left of the page) show the tweets for the account instead of the timeline from the Twitter account? Note: the plugin is using OAuth...I just don't know how to tell it to display tweets instead of the timeline.
I believe this is the code that displays the twitter info:
<?php
$user_screen_name = 'ethnecity';
$user_full_name = '(removed)';
$settings = array(
'consumer_key' => '(removed)',
'consumer_secret' => '(removed)',
'access_token' => '(removed)',
'access_token_secret' => '(removed)');
$api_url = 'https://api.twitter.com/1.1/statuses/home_timeline.json';
$api_params = array(
'count' => 40,
'contributor_details' => 'false',
'include_entities' => 'false');
// OAuth:
function oauth_encode($data){
if(is_array($data)){
return array_map('oauth_encode', $data);
} else if(is_scalar($data)) {
return str_ireplace(array('+', '%7E'), array(' ', '~'), rawurlencode($data));
} else {
return '';
}}
// OAuth base settings
$oauth_params = array(
'oauth_consumer_key' => $settings['consumer_key'],
'oauth_nonce' => md5(microtime() . mt_rand()),
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_timestamp' => time(),
'oauth_token' => $settings['access_token'],
'oauth_version' => '1.0',
);
// Sign OAuth params
$sign_params = array_merge($oauth_params, $api_params);
uksort($sign_params, 'strcmp');
foreach ($sign_params as $k => $v) {
$sparam[] = oauth_encode($k) . '=' . oauth_encode($v);
}
$sparams = implode('&', $sparam);
$base_string = 'GET&' . oauth_encode($api_url) . '&' . oauth_encode($sparams);
$signing_key = oauth_encode($settings['consumer_secret']) . '&' . oauth_encode($settings['access_token_secret']);
$oauth_params['oauth_signature'] = oauth_encode(base64_encode(hash_hmac('sha1', $base_string, $signing_key, TRUE)));
// Set Authorization header:
uksort($oauth_params, 'strcmp');
foreach ($oauth_params as $k => $v) {
$hparam[] = $k . '="' . $v . '"';
}
$hparams = implode(', ', $hparam);
$headers = array();
$headers['Expect'] = '';
$headers['Authorization'] = 'OAuth ' . $hparams;
foreach ($headers as $k => $v) {
$curlheaders[] = trim($k . ': ' . $v);
}
// Format params:
foreach ($api_params as $k => $v) {
$rparam[] = $k . '=' . $v;
}
$rparams = implode('&', $rparam);
// echo "curl --get '" . $api_url . "' --data '" . $rparams . "' --header 'Authorization: OAuth " . $hparams . "' --verbose" . PHP_EOL;
// GET:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $api_url . '?' . $rparams);
curl_setopt($ch, CURLOPT_HTTPHEADER, $curlheaders);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 10 );
$response = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$info = curl_getinfo($ch);
$error = curl_error($ch);
$errno = curl_errno($ch);
curl_close($ch);
function get_twitterfeeds(){
global $code; global $response;
if($code != 200){
//echo 'Error' . PHP_EOL;
//echo $code . PHP_EOL;
//print_r($response);
//print_r($info);
} else {
$all = json_decode($response, true);
//echo '<pre />';
// print_r($all);
//exit;
return $all;
}
}
?>
Your code should be modified so as to retrieve user's timeline. As per the current code it should return only tweets present on your timeline.
If you need only your's or a particular user's feed , your code should be modified in such a way that resource URL should be changed.
$api_url = 'https://api.twitter.com/1.1/statuses/user_timeline.json';
$api_params = array(
'screen_name' => 'ethnecity'
'count' => 40,
'contributor_details' => 'false',
'include_entities' => 'false'
);
Please verify the document https://dev.twitter.com/docs/api/1.1/get/statuses/user_timeline
i have 2 PHP files, one index.php and the other one paypal.php.
The code for paypal.php is:
<?php
session_start();
$client_id = 'xxxxxxxxxxxx';
$client_secret = 'xxxxxxxxxxxxxxxxxxxx';
$scopes = 'email profile';
$app_return_url = 'http://xxx.com/xxx/paypal.php';
$nonce = time() . rand();
$code = $_REQUEST["code"];
if(empty($code)) {
$_SESSION['state'] = md5(uniqid(rand(), TRUE));
$paypal_auth_url = "https://www.paypal.com/webapps/auth/protocol/openidconnect/v1/authorize?"
."client_id=".$client_id
."&response_type=code"
."&scope=".$scopes
."&nonce=".$nonce
."&state=".$_SESSION['state']
."&redirect_uri=".urlencode($app_return_url);
header("Location: $paypal_auth_url");
}else{
$token_url = "https://www.paypal.com/webapps/auth/protocol/openidconnect/v1/tokenservice";
$postvals = "client_id=".$client_id
."&client_secret=".$client_secret
."&grant_type=authorization_code"
."&code=".$code;
$ch = curl_init($token_url);
$options = array(
CURLOPT_POST => 1,
CURLOPT_VERBOSE => 1,
CURLOPT_POSTFIELDS => $postvals,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_SSLVERSION => 3
);
curl_setopt_array( $ch, $options );
$response = curl_exec($ch);
curl_close($ch);
$atoken = json_decode($response);
$profile_url = "https://www.paypal.com/webapps/auth/protocol/openidconnect/v1/userinfo?"
."schema=openid"
."access_token=".$atoken->access_token;
$ch = curl_init($profile_url);
$options = array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_SSLVERSION => 3
);
curl_setopt_array( $ch, $options );
$response = curl_exec($ch);
curl_close($ch);
$profile= json_decode($response,true);
$_SESSION['paypal_user'] = "true";
$_SESSION['profile'] = $profile;
echo("<script> top.location.href='index.php'</script>");
}
?>
The code for index.php is:
<?php
session_start();
// LOGOUT
if ($_GET['logout'] == 'true'){
$_SESSION['paypal_user']="";
}
if (strlen($_SESSION['paypal_user'])){
// LOGGED USER
echo "<pre>";
print_r($_SESSION['profile']);
echo "</pre>";
echo "<br><BR> <a href='?logout=true'>LOGOUT</a>";
}else{
// LOGIN
?>
<a href='paypal.php' title='Paypal oAuth Login'>
<img src='https://www.paypalobjects.com/en_US/Marketing/i/btn/login-with-paypal-button.png'>
</a>
<?
}
?>
Any ideas why this code is not working? I tried var_dump json_decode and it returns null.
Thank you!
I may be wrong, but I believe you scopes need to be...
"scopes": "email https://uri.paypal.com/services/paypalattributes",
The URL is the profile
simply add '&' on before access token,he missed & symbol between two variables
$profile_url = "https://www.paypal.com/webapps/auth/protocol/openidconnect/v1/userinfo?" ."schema=openid" ."**&**access_token=".$atoken->access_token;