I have created one application in YiiFramework which has two functionalities.
1. Login to google
For login to google, I have followed the tutorial on below website.
Tutorial : https://github.com/Nodge/yii-eauth
Tutorial Demo : http://nodge.ru/yii-eauth/demo/login
2 Get calendar using Zend_Gdata Library
Tutorial : http://www.bcits.co.in/googlecalendar/index.php/site/install
Tutorial Demo : http://www.bcits.co.in/googlecalendar/index.php/site/page?view=about
[1st Step] I get successfully login to my application using yii-eauth.
[2nd Step] when I need to use calendar, I am giving hard coded gmail Id and password.
I am accessing calendar in this way.
<?php
$user = 'your gmail username';
$pass ='your gmail password';
Yii::app()->CALENDAR->login($user, $pass);
?>
login() in googlecalendar.php file.
public function login($user, $pass) {
$service = Zend_Gdata_Calendar::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);// It uses hard-coded gmail/password to get login again
$calenderlist = $this->outputCalendarList($client);
$events = $this->outputCalendar($client);
$calendardate = $this->outputCalendarByDateRange($client, $startDate = '2011-05-01', $endDate = '2011-06-01');
.........
}
Does Zend_Gdata library contain any function which automatically gets calendar of current user without again logging in(hard-coded here).
Stuck with this. Appreciate helps. Thanks
From my understanding, Zend_Gdata_ClientLogin sets some parameters for $client which is the object returned. See the following excerpt from that function:
if ($loginToken || $loginCaptcha) {
if ($loginToken && $loginCaptcha) {
$client->setParameterPost('logintoken', (string) $loginToken);
$client->setParameterPost('logincaptcha', (string) $loginCaptcha);
} else {
require_once 'Zend/Gdata/App/AuthException.php';
throw new Zend_Gdata_App_AuthException(
'Please provide both a token ID and a user\'s response ' .
'to the CAPTCHA challenge.');
}
}
What you could do is store that token or that $client object (which is an instance of Zend_Gdata_HttpClient). Pretty much all of the Zend_Gdata components accept a $client argument.
Check out the __construct() method for Zend_Gdata_Calendar:
So anyway, you would want something similar to this logic (sorry I'm not familiar with Yii):
$client = Yii::app()->getClient();
if (!$client) {
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
Yii::app()->setClient($client);
}
Of course, you would have to then define that getClient() method somehow.
Hope this helps!
Related
I had a problem with updating user cover pic using php(zend framework) and Oauth.
I have added to my composer.json the following lines:
"require" : {
"google/auth": "0.7",
"google/apiclient" : "^2.0.0#RC"
}
After that I made composer-install + composer-update using and oppp I get the library inside my vendor.
I have configured my application inside google developing console, following the official tutorial by google :D
Now inside my controller I could easily request google web service using this method :
public function googleplusAction()
{
Zend_Loader::loadFile("HttpPost.class.php");
$client_id = "id_here";
$client_secret = "secret_here";
$application_name = "application_name_here";
$redirect_uri = "redirection_uri_here";
$oauth2_server_url = 'https://accounts.google.com/o/oauth2/auth';
$query_params = array(
'response_type' => 'code',
// The app needs to use Google API in the background
'client_id' => $client_id,
'redirect_uri' => $redirect_uri,
'scope' => 'https://www.googleapis.com/auth/userinfo.profile'
);
$forward_url = $oauth2_server_url . '?' . http_build_query($query_params);
header('Location: ' . $forward_url);
}
After that I get redirected to my redirection URI , and in the bar address I get a new variable 'code'.
Until now, I hope everything is fine , coming to the most important part , the controller of the redirection URI page , using the 'code' variable that I have talked about it before I tried to get an access token, but I was failed.
This is the method that should set a new cover picture on google plus :
$client_id = "client-id";
$client_secret = "g+-secret";
$application_name = "my-app-name";
$redirect_uri = "my-uri-on-g+";
$client = new Google_Client();
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setRedirectUri($redirect_uri);
$service = new Google_Service_Oauth2($client);
$client->addScope(Google_Service_Oauth2::USERINFO_PROFILE);
$client->authenticate($_GET['code']); // I have the right code, and I am being authenticated
$plus = new Google_Service_Plus($client);
$person = $plus->people->get('me');
var_dump($person);
$pic = $this->session->image['generatedAbs'];
$gimg = new Google_Service_Plus_PersonCover();
$source = new Google_Service_Plus_PersonCoverCoverPhoto();
$source ->setUrl("$photo-that-i-wanted-to-put-on-g+");
$gimg->setCoverPhoto($source);
$person->setCover($gimg);}
So my questions are :
How can I change my google plus cover picture to a new png or JPEG picture that I have already in my project ?
inside the G+ library I found this method :
Google_Service_Plus_PersonCoverCoverPhoto();
inside a class called
Google_Service_Plus_PersonCover();
But how can I use it ?
I think that methods Google_Service_Plus_PersonCoverCoverPhoto() and Google_Service_Plus_PersonCover() are used by the client library to set it when the information is retrieved. It is not meant for you to be able to update the users cover on Google+, if that does work it will only update the class object which really there is no point in doing (IMO).
var_dump($person->Cover);
If you check the Plus.People documentation you will notice there are no update or patch methods. This is because its not possible to update a users information programmatically at this time.
Answer: Your inability to update the users cover picture has nothing to do with Oauth it has to do with the fact that this is not allowed by the API. Unfortunately it looks like you have done a lot of work for nothing this is why it is good to always consult the documentation before you begin you would have seen that it was not possible, and could have avoided a lot of unnecessary stress on yourself.
I would like to use dailymotion api to get infos of my own private videos.
SO ...
I have a Dailymotion account
I have created an API key and secret key
I downloaded the PHP class
I would like to get infos of my privates videos to diplay it on my website...
So i think I need to authenticate my account and after get the code...
but it does not work :'(
Please could you give me a sample code to do this ?
my test code is like that for now
<?php
error_reporting(E_ALL & ~E_NOTICE);
ini_set('display_errors', 1);
$apiKey = 'xxxx';
$apiSecret = 'xxxx';
require_once 'Dailymotion.php';
// Instanciate the PHP SDK.
$api = new Dailymotion();
// Tell the SDK what kind of authentication you'd like to use.
// Because the SDK works with lazy authentication, no request is performed at this point.
$api->setGrantType(Dailymotion::GRANT_TYPE_AUTHORIZATION, $apiKey, $apiSecret);
$api = new Dailymotion();
try
{
$result = $api->get(
'/video/privateVideoId',
array('fields' => array('id', 'title', 'owner'))
);
}
catch (DailymotionAuthRequiredException $e)
{
echo $e->getMessage();
// If the SDK doesn't have any access token stored in memory, it tries to
// redirect the user to the Dailymotion authorization page for authentication.
//return header('Location: ' . $api->getAuthorizationUrl());
}
catch (DailymotionAuthRefusedException $e)
{
echo $e->getMessage();
// Handle the situation when the user refused to authorize and came back here.
// <YOUR CODE>
}
trace($result);
function trace($d) {
echo '<pre>';
var_dump($d);
echo '</pre>';
}
?>
and the result is :
This user is not allowed to access this video.
so i think there is a problem with authentication ... but i do not understant how to do that only with php
thanks a lot for your help
It looks like there are a couple of issues in your code and in the way you authenticate:
1) your code: you call $api = new Dailymotion(); and then set the authorization grant type with your api key and secret. But next line, you override all that by re-writing $api = new Dailymotion();. So I recommend you to remove this line, otherwise it is like you have not set any grant type!
2) There is an interesting code sample regarding authorization grant type in php, doing exactly what you're trying to do, at https://developer.dailymotion.com/tools/sdks#sdk-php-grant-authorization
Your code is very similar, why did you comment the return header('Location: ' . $api->getAuthorizationUrl()); part when catching DailymotionAuthRequiredException ? This part redirects the user to the auth page so he/she can authenticate.
I also recommend to have a look at others grant types for authentication, such as password grant type (https://developer.dailymotion.com/tools/sdks#sdk-php-grant-password)
When using the below code to attempt to list messages received by a brand new gmail account I just set up, I get
[Google_Service_Exception] Error calling GET https://www.googleapis.com/gmail/v1/users/myGmailAccount%40gmail.com/messages: (500) Backend Error
I know the validation portion is working correctly because I'm able to make minor modifications and query the books api as shown in this example. Below is the code I'm using to attempt to query recent messages received...
const EMAIL = 'myGmailAccount#gmail.com';
private $permissions = [
'https://www.googleapis.com/auth/gmail.readonly'
];
private $serviceAccount = 'xxxxxxxxxxxxxxxxx#developer.gserviceaccount.com';
/** #var Google_Service_Gmail */
private $gmail = null;
/** #var null|string */
private static $serviceToken = null;
public function __construct()
{
$client = new Google_Client();
$client->setApplicationName($this->applicationName);
$this->gmail = new Google_Service_Gmail($client);
//authentication
if (isset(self::$serviceToken)) {
$client->setAccessToken(self::$serviceToken);
}
$credentials = new Google_Auth_AssertionCredentials(
$this->serviceAccount,
$this->permissions,
$this->getKey()
);
$client->setAssertionCredentials($credentials);
if($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($credentials);
}
self::$serviceToken = $client->getAccessToken();
}
public function getMessages()
{
$this->gmail->users_messages->listUsersMessages(self::EMAIL);
}
I have granted API access to gmail:
The 500 makes me believe this is an internal error with the gmail API or I'm missing something the PHP client isn't validating.
This one work for me. My understanding is service account doesn't have a mailbox and it's not too sure which mailbox it should work on. So you can't use listUsersMessages() function to get all messages.
So you will need to specify which email address that the service account need to work on.
Make sure that the scope has been allowed on Web App API to
1. Add this line:
$credentials->sub = self::EMAIL;
Before:
$client->setAssertionCredentials($credentials);
2. Then Update your getMessages() to:
$this->gmail->users_messages->listUsersMessages("me");
Hope this helps!
I imagine the account has logged in to the web interface already, right? Have you tried with a separate user? How about doing something like labels list instead? Did you try using the APIs explorer site? https://developers.google.com/apis-explorer/#p/gmail/v1/
Can you provide the first 5 digits of the developer's client ID (it's not secret anyway) so I can try to track down the error?
For this to work you have to impersonate an user account (the service account doesn't have a mailbox, as lthh89vt points out).
If you try to access the mailbox directly you will get the (500) Back End error.
The full code is:
$client_email = '1234567890-a1b2c3d4e5f6g7h8i#developer.gserviceaccount.com';
$private_key = file_get_contents('MyProject.p12');
$scopes = array('https://www.googleapis.com/auth/gmail.readonly');
$user_to_impersonate = 'user#example.org';
$credentials = new Google_Auth_AssertionCredentials(
$client_email,
$scopes,
$private_key,
'notasecret', // Default P12 password
'http://oauth.net/grant_type/jwt/1.0/bearer', // Default grant type
$user_to_impersonate,
);
$client = new Google_Client();
$client->setAssertionCredentials($credentials);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion();
}
$service = new Google_Service_Gmail($client);
$results = $service->users_messages->listUsersMessages('me');
Full instructions can be found on Google APIs Client Library for PHP
I've been Googling for quite some time now for some ideas or a guide on how to integrate OAuth (v1.0 & v2.0) alongside the standard Laravel 4 Eloquent authentication driver.
Essentially, I'd like to be able for site visitors to create an account via their existing Google, Facebook, or Twitter accounts, or via the standard email/password authentication. Certain user information such as email, first and last names, and avatar are important for me to have stored in a unified users table.
So far the projects I've looked at seem to support only OAuth and do away with the standard method. These projects include: eloquent-oauth, and oauth-4-laravel.
At this point, I might just roll my own solution, but I'm hoping some of you guys might have better advice for me!
TL;DR: I'm stuck at trying to find a simple and secure way to allow OAuth and standard Eloquent user authentication in Laravel. Halp.
I think the easiest way would be to use this service provider that you mention "artdarek/oauth-4-laravel" and then store the values as usual and log them in.
/**
* Login user with facebook
*
* #return void
*/
public function loginWithFacebook() {
// get data from input
$code = Input::get( 'code' );
// get fb service
$fb = OAuth::consumer( 'Facebook' );
// check if code is valid
// if code is provided get user data and sign in
if ( !empty( $code ) ) {
// This was a callback request from facebook, get the token
$token = $fb->requestAccessToken( $code );
// Send a request with it
$result = json_decode( $fb->request( '/me' ), true );
// store new user or login if user exists
$validator = Validator::make($result, array(
'email'=>'required|email|unique:users'
));
if ($validator->passes()) {
# Save user in DB
$user = new User;
$user->username = $result['name'];
$user->email = $result['email'];
$user->save();
}else {
$user = User::findByUsernameOrFail($result['name']);
}
Auth::login($user);
}
// if not ask for permission first
else {
// get fb authorization
$url = $fb->getAuthorizationUri();
// return to facebook login url
return Redirect::to( (string)$url );
}
}
I want to allow anyone register on my site, to upload their videos on my own youtube user channel.
I don't want them to comment any videos, or anything that requires their own login credentials.
Should I use: ClientLogin authorization ?
If so, how can I get a token so that I can allow my site to interact with my youtube channel account?
Any lights here will be greatly appreciated, since I'm kinda lost here.
I have accomplished this using ClientLogin. A basic class is below. This class returns an instance of Zend HTTP Client that is ready to make authenticated requests.
<?php
class GoogleAuthenticator {
public static function authenticate($logger) {
$tokenObj = new Token();
try {
$token = $tokenObj->get($token_name);
if(!empty($token)) {
//load a new HTTP client with our token
$logger->info('Using cached token: ' . $token);
$httpClient = new Zend_Gdata_HttpClient();
$httpClient->setConfig(array(
'maxredirects' => 0,
'strictredirects' => true,
'useragent' => 'uploader/v1' . ' Zend_Framework_Gdata/' . Zend_Version::VERSION
)
);
$httpClient->setClientLoginToken($token);
//attempt to use our token to make an authenticated request. If the token is invalid
// an exception will be raised and we can catch this below
$yt = new Zend_Gdata_YouTube($httpClient, 'uploader/v1', '', $youtube_api_key);
$query = new Zend_Gdata_YouTube_VideoQuery();
$query->setFeedType('top rated');
$query->setMaxResults(1);
$yt->getPlaylistListFeed(null, $query); //ignore the response!
} else {
$logger->info('Generating new HTTP client');
// Need to create a brand new client+authentication
$authenticationURL= 'https://www.google.com/youtube/accounts/ClientLogin';
$httpClient =
Zend_Gdata_ClientLogin::getHttpClient(
$username = YOUTUBE_USERNAME_PROD,
$password = YOUTUBE_PASSWORD_PROD,
$service = 'youtube',
$client = null,
$source = 'uploader/v1',
$loginToken = null,
$loginCaptcha = null,
$authenticationURL);
// get the token so we can cache it for later
$token = $httpClient->getClientLoginToken();
$tokenObj->destroy($token_name);
$tokenObj->insert($token, $token_name);
}
return $httpClient;
}catch(Zend_Gdata_App_AuthException $e) {
$tokenObj->destroy($token_name);
die("Google Authentication error: " . $e->getMessage());
}catch(Exception $e) {
$tokenObj->destroy($token_name);
die("General error: " . $e->getMessage());
}
} // authenticate()
} // GoogleAuthenticator
?>
You'll need to have these constants defined:
YOUTUBE_USERNAME_PROD
YOUTUBE_PASSWORD_PROD
Or modify the class to pass them in. The try/catch is needed because tokens can expire, so you need to a way to refresh them. Also, you need to make a dummy request to ensure the Token is valid even after you create it.
Keep in mind that YouTube (well, as of 2 years ago or so) prevented you from uploading a video more of than every 10 minutes, which makes your use-case pretty difficult. That is, you cannot allow multiple videos being uploaded on a single accounts behalf, more of than every 10 min. But YouTube might have lifted this since then. Good luck
Since I didn't find any complete solutions for API V3 in the documentation I've been exploring the Internet for a solution. In the end I ported the Python example to PHP and wrote a blog post about it for other people that have the same problem:
Uploading a video to youtube through api version 3 in PHP
This blogpost uses the Youtube V3 api with OAuth2 so you don't have to worry about it being deprecated. All other functions (ClientLogin, AuthSub and OAuth 1.0) in V2 are all deprecated as of April 20, 2012.