Using Yii2 authClient to retrieve scope data from Facebook after successful authentication - facebook

Currently working with the Yii2 framework and using the includable \yiisoft\yii2-authclient OAuth abstraction class. I am able to connect and authenticate via Facebook but can not figure out how to access secondary data available through the OAuth2 scope configuration option.
Related but vague (as it does not explain how scope applies to the situation nor how to use the authClient to retrieve the data: Login with Facebook API
Config
'authClientCollection' => [
'class' => 'yii\authclient\Collection',
'clients' => [
'facebook' => [
'authUrl' => 'https://www.facebook.com/dialog/oauth',
'class' => 'yii\authclient\clients\Facebook',
'clientId' => '*****',
'clientSecret' => '*****',
'scope' => [
'email',
'public_profile',
'user_about_me',
'user_location',
'user_work_history',
]
],
],
],
Controller setup:
public function actions()
{
return [
'auth' => [
'class' => 'yii\authclient\AuthAction',
'successCallback' => [$this, 'onAuthSuccess'],
],
];
}
...
/**
* [onAuthSuccess description]
*
* #param [type] $client [description]
* #return [type] [description]
*/
public function onAuthSuccess($client)
{
$attributes = $client->getUserAttributes();
echo '<pre>';
print_r( $attributes );
echo '</pre>';
exit;
...
The returned object is as follows:
yii\authclient\clients\Facebook Object
(
[authUrl] => https://www.facebook.com/dialog/oauth
[tokenUrl] => https://graph.facebook.com/oauth/access_token
[apiBaseUrl] => https://graph.facebook.com
[scope] => Array
(
[0] => email
[1] => public_profile
[2] => user_about_me
[3] => user_location
[4] => user_work_history
)
[attributeNames] => Array
(
[0] => name
[1] => email
)
[version] => 2.0
...
)
How would I access the user's user_about_me data?
*Edited to add controller logic that provides the data dump.

You can get following info by setting this values in attributeNames
id
name
first_name
last_name
age_range
link
gender
locale
picture
timezone
updated_time
verified
In your config file
...
'components' => [
...
'authClientCollection' => [
'class' => 'yii\authclient\Collection',
'clients' => [
'facebook' => [
'class' => 'yii\authclient\clients\Facebook',
'authUrl' => 'https://www.facebook.com/dialog/oauth',
'clientId' => 'YOUR APP CLIENT ID',
'clientSecret' => 'YOUR APP CLIENT SECRET',
'attributeNames' => [
'id',
'name',
'first_name',
'last_name',
'link',
'about',
'work',
'education',
'gender',
'email',
'timezone',
'locale',
'verified',
'updated_time',
],
],
],
],
...
],
...
Important Links and references
https://developers.facebook.com/docs/facebook-login/permissions/v2.2
Login with Facebook API
What data can be obtained about a user who logs in with Facebook Oauth?
https://developers.facebook.com/tools/explorer/?method=GET&path=me%3Ffields%3Did%2Cname%2Cemail&version=v2.7
https://developers.facebook.com/docs/graph-api/using-graph-api/#fieldexpansion

You should use getUserAttributes method:
public function actions()
{
return [
[
'class' => 'yii\authclient\AuthAction',
'successCallback' => [$this, 'successCallback']
]
];
}
/**
* #param OAuth2 $client
*/
public function successCallback($client)
{
$attributes = $client->getUserAttributes();
...
}

Related

Request timeout - integrate third party library with codeigniter 3

Im working on API integration InPost API Create shippment. I try integrate third party library inpost with codeigniter 3 from GitHub.
https://github.com/imper86/php-inpost-api
I install this library via composer.
View:
<?php echo form_open('inpost_controller/inpost_shippment_post'); ?>
<div class="form-group">
</div>
</div>
<?php echo form_close(); ?><!-- form end -->
Then I call in controller:
require FCPATH . 'vendor/autoload.php';
Full code file Controller:
<?php
defined('BASEPATH') or exit('No direct script access allowed');
require FCPATH . 'vendor/autoload.php';
use Imper86\PhpInpostApi\Enum\ServiceType;
use Imper86\PhpInpostApi\InpostApi;
class Inpost_controller extends Admin_Core_Controller
{
public function __construct()
{
parent::__construct();
}
/**
* Create shippment Inpost Post
*/
public function inpost_shippment_post()
{
$token = 'xxxxx';
$organizationId = 'xxxxx';
$isSandbox = true;
$api = new InpostApi($token, $isSandbox);
$response = $api->organizations()->shipments()->post($organizationId, [
'receiver' => [
'name' => 'Marek Kowalczyk',
'company_name' => 'Company name',
'first_name' => 'Jan',
'last_name' => 'Kowalski',
'email' => 'test#inpost.pl',
'phone' => '888888888',
'address' => [
'street' => 'Malborska',
'building_number' => '130',
'city' => 'Kraków',
'post_code' => '30-624',
'country_code' => 'PL',
],
],
'sender' => [
'name' => 'Marek Kowalczyk',
'company_name' => 'Company name',
'first_name' => 'Jan',
'last_name' => 'Kowalski',
'email' => 'test#inpost.pl',
'phone' => '888888888',
],
'parcels' => [
['template' => 'small'],
],
'insurance' => [
'amount' => 25,
'currency' => 'PLN',
],
'cod' => [
'amount' => 12.50,
'currency' => 'PLN',
],
'custom_attributes' => [
'sending_method' => 'parcel_locker',
'target_point' => 'KRA012',
],
'service' => ServiceType::INPOST_LOCKER_STANDARD,
'reference' => 'Test',
'external_customer_id' => '8877xxx',
]);
$shipmentData = json_decode($response->getBody()->__toString(), true);
while ($shipmentData['status'] !== 'confirmed') {
sleep(1);
$response = $api->shipments()->get($shipmentData['id']);
$shipmentData = json_decode($response->getBody()->__toString(), true);
}
$labelResponse = $api->shipments()->label()->get($shipmentData['id'], [
'format' => 'Pdf',
'type' => 'A6',
]);
file_put_contents('/tmp/inpost_label.pdf', $labelResponse->getBody()->__toString());
}
}
When I post form, after 30 sec I get error 500 Internar Error Server Request timout.
And now im not sure how to debug now. I enable error log in CI3 application/logs/ I open this file but I not see any error related to this.
Could be a defect, or missing http2 setup/cfg.
Since the header in https2 protocol has shorter header on packs.
Not sure doe
https://caniuse.com/http2 < short http2 (TLS, HTTPS) overview
https://factoryhr.medium.com/http-2-the-difference-between-http-1-1-benefits-and-how-to-use-it-38094fa0e95b < http2 as protocol overview in 5 min

Argument 1 passed to GuzzleHttp\Client::send() must implement interface

hi I am new to laravel and I am trying to consume the api with laravel 8 I have a problem with my POST and I do not understand
public function storeEntreprise(Request $request){
$request->validate([
'name' => 'required',
'email' => 'required',
'phone_number'=>'required',
'address' => 'required',
'password' => 'required',
'password_confirmation' => 'required'
]);
$client = new Client();
$post = $request->all();
$url = "http://flexy-job.adsyst-solutions.com/api/entreprises-store";
$create = $client->request('POST', $url, [
'headers' => [
'Content-Type' => 'text/html; charset=UTF8',
],
'form-data' => [
'name' => $post['name'],
'email' => $post['email'],
'phone_number' => $post['phone_number'],
'address' => $post['address'],
'logo' => $post['logo'],
'password' => $post['password'],
'password_confirmation' => $post['password_confirmation']
]
]);
//dd($create->getBody());
echo $create->getStatusCode();
//echo $create->getHeader('Content-Type');
echo $create->getBody();
$response = $client->send($create);
return redirect()->back();
}
Can you help me please
You calling (accidentally?) $response = $client->send($create); where $create is response of API request you made ($create = $client->request('POST', $url, ...).
So PHP reports you that you can't pass ResponseInterface where RequestInterface required.
Also, you echo's body of response, and return redirect response at same time. So browser will not show you API response (because of instance back redirect).

Way to redirect login page if user not login

I want to redirect user to login page if he is not logged on page. But i have actionLogin in my registrationController
So when I use in my common/main:
'as beforeRequest' => [ //if guest user access site so, redirect to login page.
'class' => 'yii\filters\AccessControl',
'rules' => [
[
'actions' => ['login', 'error'],
'allow' => true,
],
[
'allow' => true,
'roles' => ['#'],
],
],
],
It always redirect me to index.php?r=site%2Flogin
Is it possible to change main login redirect to index.php?r=registration%2Flogin?
If it possible where I should overwrite code or change something..
'user' => [ 'loginUrl' => ['registration/login'], ],
resolve problem but when I want to go to registration/index to signup user it redirect me to registration/login.
Is it possible to rule out this url from being enforced? I Want to make index.php?r=registration the only available path.
And here is my facebook login; I want to enable this too
public function oAuthSuccess($client) {
// get user data from client
$userAttributes = $client->getUserAttributes();
$user = User::find()->where(['Email' => $userAttributes['email']])->one();
if (!$user) {
$newuser = New SignupForm();
$newuser->oAuthSuccess($client);
$user = User::find()->where(['Email' => $userAttributes['email']])->one();
if ($newuser->validate() && Yii::$app->getUser()->login($user)) {
Yii::$app->session->setFlash('success', Yii::t('app', 'Udało się poprawnie zalogować. Prosimy dokonać zmian w ustawianiach profilu.'));
return $this->redirect('index.php?r=content/news');
}
}
Yii::$app->user->login($user);
}
In your app/config/web.php (for basic template) or
app/frontend/config/main.php (for advance template) - reference
return [
// ...
'components' => [
// ...
'user' => [
'identityClass' => 'common\models\UserIdentity',
'enableAutoLogin' => true,
'loginUrl'=>['registration/login']
],
// ...
and in your controller for eg RegistrationController.php
// ...
class RegistrationController extends Controller
{
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['login', 'signup'], // those action only which guest (?) user can access
'allow' => true,
'roles' => ['?'],
],
[
'actions' => ['home', 'update'], // those action only which authorized (#) user can access
'allow' => true,
'roles' => ['#'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}
// ...
The simple way is using index.php from backend web or public directory
<?php
// comment out the following two lines when deployed to production
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
require __DIR__ . '/../../vendor/autoload.php';
require __DIR__ . '/../../vendor/yiisoft/yii2/Yii.php';
$config = require __DIR__ . '/../../config/web.php';
$config["controllerNamespace"]='app\controllers\backend';
(new yii\web\Application($config))->run();
if(Yii::$app->user->isGuest){
$request_headers = apache_request_headers();
$srv=$request_headers['Host'];
header("Location: https://".$srv);
die();
}

Missing CreditCard Class when using Omnipay Paypal for Laravel 5

Here are the repo included in my composer:
omnipay &
paypal
In my config/laravel-omnipay.php:
'gateways' => [
'paypal' => [
'driver' => 'PayPal_Rest',
'options' => [
'solutionType' => '',
'landingPage' => '',
'headerImageUrl' => ''
]
]
]
Here is in my Controller:
// omnipay start
$gateway = Omnipay::create('PayPal_Rest');
// Initialise the gateway
$gateway->initialize(array(
'clientId' => 'xxxxxx',
'secret' => 'xxxxxx',
'testMode' => true, // Or false when you are ready for live transactions
));
// Create a credit card object
// DO NOT USE THESE CARD VALUES -- substitute your own
$card = new CreditCard(array(
'firstName' => $request->firstname,
'lastName' => $request->lastname,
'number' => $request->cardnumber,
'expiryMonth' => $month_year[0],
'expiryYear' => $month_year[1],
'cvv' => $request->ccv,
'billingAddress1' => $request->address
/*
'billingCountry' => 'AU',
'billingCity' => 'Scrubby Creek',
'billingPostcode' => '4999',
'billingState' => 'QLD',*/
));
// Do an authorisation transaction on the gateway
$transaction = $gateway->authorize(array(
'amount' => '100',
'currency' => 'USD',
'description' => $eventName->event_title,
'card' => $card,
));
$response = $transaction->send();
if ($response->isSuccessful()) {
echo "Authorize transaction was successful!\n";
// Find the authorization ID
$auth_id = $response->getTransactionReference();
}
I've got this error:
Class 'App\Http\Controllers\CreditCard' not found
Note: If I use RestGateway to replace PayPal_Rest, I get this error instead:
Class '\Omnipay\RestGateway\Gateway' not found
Searching an answer for a long time but didn't find a solution that works for me. So, not entirely sure how to proceed.
You need to have this at the top of your class file:
use Omnipay\Common\CreditCard;
$creditCard = new \Omnipay\Common\CreditCard([...]);
Backslash
Further reading: https://stackoverflow.com/questions/4790020/what-does-a-backslash-do-in-php-5-3#:~:text=%5C%20(backslash)%20is%20the%20namespace,name%20in%20the%20current%20namespace.
The issue is because it will fetch the class from the global namespace - rather than the current namespace.

Hashing passwords and AuthComponent

I'm trying to login in my CakePHP 2.0 application but I always get the login error.
In the official documentation and the tutorial I've read how to hash the passwords, but I still get the login error, here is how I did it:
// Users Model
public function beforeSave ($options = array ()) {
$this->data['User']['password'] = AuthComponent::password($this->data['User']['password']);
return true;
}
// Users Controller
public $components = array ('Acl', 'Session',
'Auth' => array (
'authenticate' => array (
// login e logout sono di default i seguenti controller e views
// 'loginRedirect' => array ('controller' => 'users', 'action' => 'login'),
// 'logoutRedirect' => array ('controller' => 'users', 'action' => 'logout'),
'Form' => array (
'fields' => array (
// il valore default
'username' => 'email'
),
'scope' => array (
'User.active' => 1
)
)
),
'authError' => 'Login error message I get'
));
public function login () {
if ($this->request->is('post')) { // if the request came from post data and not via http (useful for security)
// the password is hashed in User Model in beforeSave method as read on documentation
// debug ($this->data);
if ($this->Auth->login()) {
$id = $this->Auth->user('id');
return $this->redirect(array('controller'=>'users', 'action'=>$id, $this->Auth->user('username')));
} else {
$this->Session->setFlash('Login error message', 'default', array(), 'auth');
}
}
}
In the view I have this:
// the view login.ctp
echo $this->Form->text('User.email', array('id'=>'email', 'value'=>'your#email.com'));
echo $this->Form->password('User.password', array('id'=>'password', 'value'=>'password'));
If I try to debug the data I get this:
// in the controller
debug($this->data);
// in the view
Array
(
[User] => Array
(
[email] => the#email.com
[password] => thepass // not hashed
)
)
I can't login because I get always the Login error message. How can I fix it?
Vitto,
(1) Which error message is displayed?
(2) Just for the record, be sure sessionFlash is printed at layout!
echo $this->Layout->sessionFlash();
(3) How did you set your Auth component? For example, in my AppController I've set this way:
public $components = array(
'Session',
'Cookie',
'Acl',
/**
* Default is authorize option is ActionsAuthorize.
* In this case, system uses AclComponent to check for permissions on an action level.
* learn more: http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#authorization
*/
'Auth'=> array(
'authorize' => array(
'Actions' => array('actionPath' => 'controllers')
),
'authenticate' => array(
'Form' => array(
'fields' => array('username' => 'email', 'password' => 'password')
)
)
)
);
(4) Finally, I believe (must be sure) there is no need to manually hash password to perform login. At least, after correct configuration, this code works for me:
if ($this->request->is('post')) {
if ($this->Auth->login()) {
// recirect stuffs