I have a function for Facebook authentication.
public function loginWithFacebook(Request $request){
// get data from request
$code = $request->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 ( ! is_null($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?fields=name,email,gender,age_range'), true);
print_r($result1);
}
// if not ask for permission first
else
{
// get fb authorization
$url = $fb->getAuthorizationUri();
// return to facebook login url
return redirect((string)$url);
}
}
I want to call this function from another controller.
So I do this:
app('App\Http\Controllers\socialMedia')->loginWithFacebook(Request $request);
but it returns the error
syntax error, unexpected '$request' (T_VARIABLE)
How do I solve this?
public function loginWithFacebook(Request $request){
This is called type hinting. The method is declared in a way that it will only accept a first parameter that is an instance of Request.
app('App\Http\Controllers\socialMedia')->loginWithFacebook(Request $request);
That is a method call, and in those you just pass the parameter – to specify a type at this point makes no sense.
So the correct way to call the method should be
app('App\Http\Controllers\socialMedia')->loginWithFacebook($request);
Related
I have an endpoint which is doing something (facade-endpoint), and then redirecting to another endpoint (endpoint) in the same application. What I'm trying to do here is I want to pass few parameters on redirection, but I don't want to allow others to pass them when they call the second endpoint directly.
For example:
public function facadeEndpoint(FacadeEndpointRequest $request)
{
$var1 = SomeClass::doSomething();
$var2 = SomeClass::doSomethingElse();
$request = Request::create('endpoint', 'GET');
return app()->handle($request); // I want to pass $var1 and $var2 here, so that they don't get recalculated once again after the redirection
}
public function endpoint(EndpointRequest $request)
{
$var1 = SomeClass::doSomething();
$var2 = SomeClass::doSomethingElse(); // If the request came from facade-endpoint, I want to use passed values instead of calling SomeClass functions again
// do something...
}
However as I mentioned, I don't want people to be able to pass $var1 or $var2 to the request directly - they should only be calculated in the application.
Is it possible?
Maybe you can add an additional parameter to signal that it came from facade endpoint.
$request = Request::create('endpoint', 'GET', ['internal' => true]);
Then when you receive request in your endpoint you can check whether it exists.
if ($request->has('internal')) {
// from facade endpoint
} else {
// called directly
}
The problem with this being a GET request is that parameters will be present in the url.
I integrated amazon pay into my website and i followed the instructions from Amazon Pay SDK Simple Checkout. Its all working so far, but in the last step the code example shows that i need an authorization reference id.
namespace AmazonPay;
session_start();
// Create the parameters array
$requestParameters = array();
// Refer to GetDetails.php where the Amazon Order Reference ID was set
$requestParameters['amazon_order_reference_id'] = 'AMAZON_ORDER_REFERENCE_ID';
// Confirm the order by making the ConfirmOrderReference API call
$response = $client->confirmOrderReference($requestParameters);
$responsearray['confirm'] = json_decode($response->toJson());
// If the API call was a success make the Authorize API call
if($client->success)
{
$requestParameters['authorization_amount'] = '175.00';
##################################################
############ WHERE DO I GET THIS? ################
$requestParameters['authorization_reference_id'] = 'Your Unique Reference Id';
$requestParameters['seller_authorization_note'] = 'Authorizing payment';
$requestParameters['transaction_timeout'] = 0;
$response = $client->authorize($requestParameters);
$responsearray['authorize'] = json_decode($response->toJson());
}
// If the Authorize API call was a success, make the Capture API call when you are ready to capture
for the order (for example when the order has been dispatched)
if($client->success)
{
$requestParameters['amazon_authorization_id'] = 'Parse the Authorize Response for this id';
$requestParameters['capture_amount'] = '175.00';
$requestParameters['currency_code'] = 'USD';
$requestParameters['capture_reference_id'] = 'Your Unique Reference Id';
$response = $client->capture($requestParameters);
$responsearray['capture'] = json_decode($response->toJson());
}
// Echo the Json encoded array for the Ajax success
echo json_encode($responsearray);
As shown above the 'authorization_reference_id' needs to be set. But i dont know how to get it. It isnt in my previous response for Setting a new order. Also its not included in the "confirmOrderReference" response. Did i miss something here or is the code sample not complete?
$requestParameters['authorization_reference_id'] = 'Your Unique Reference Id';
Thanks for any help
authorization_reference_id is given by you. It should be unique.
You can used the uniqid builtin function in PHP to generate that. It must be unique for every request.
$requestParameters['authorization_reference_id'] = uniqid();
I'm using the php-graph-sdk v. 5.5 to get information of a user facebook that signs up in a web. The problem is that there's no way to know if a token is valid or not, using the methods like
FacebookAuthenticationAccessToken->getExpiresAt()
and so on. Those methods always return null values even if the token is valid. I'd like to check the token validity before call the ->get() method of the main FacebookFacebook class. Is there any way to do ti?
Solved! This is not the getExpiresAt() method that must be call. This is only a getter that gets the same information you posted in the constructor of
$accessToken = new \Facebook\Authentication\AccessToken($this->accessToken, $expirationDate);
You must set the var $expirationDate to a valid timestamp, and this is directly the value that getExpiresAt() returns, so doesn't has sense to use to check the Access Token validation.
To get the correct expiration date of an access token, you must perform a remote call using a Request as follows:
try {
$response = $this->fb->get('/debug_token?input_token=' . $this->accessToken);
}
catch(\Facebook\Exceptions\FacebookResponseException $e) {
// When Graph returns an error
$this->lastError = 'FaReEx: ' . $e->getMessage();
return false;
}
catch(\Facebook\Exceptions\FacebookSDKException $e) {
// When validation fails or other local issues
$this->lastError = 'FaSDKEx: ' . $e->getMessage();
return false;
}
$graphObject = $response->getGraphObject();
return $graphObject->getProperty('expires_at'); // This is a DateTime php object
I am building a small class to handle api requests and I am running into an issue with error handling (I am also a novice at OOP so please with me) I need to restrict or throw an error with any methods in my class that require the user parameter to be set and I also need to samething if token has not been retreived and I can't seem to wrap my head around it.
This is what I have so far...
$user array is set in a config file outside of class like so (empty by default):
$user = array(
'user_email' = '',
'user_pass' = ''
);
Class for handling API (simplified for question)
class eventAPI {
private $user
private $token
public function __construct($user) {
$this->user = $user;
// if possible assign token when instantiated
$this->retrieve_token($user);
}
private function retreive_token($user) {
// Check if user parameter has been set
if($this->validate_user_parameter()) {
// use credentials to make HTTP request for token
$token = 'somerandomtoken';
// assign token property retreived value
$this->token = $token;
} else {
echo 'User parameter has not been set.' // Not real message just for testing
return FALSE;
}
}
public function show_all_events() {
// Check if token has been retreived
if($this->validate_token_retreived()) {
// Use token to retreive events list via HTTP request
} else {
echo 'API not active. No valid token detected'; // for testing purposes
return FALSE
}
}
// reduntant code... Can't wrap my head around another way for checking for token.
public function show_single_event() {
// Check if token has been retreived
if($this->validate_token_retreived()) {
// Use token to retreive events list via HTTP request
} else {
echo 'API not active. No valid token detected'; // for testing purposes
return FALSE
}
}
// This is mostly where I am confused how to solve.
private function validate_user_parameter() {
foreach($this->user as $key => $value) {
// Remove whitespace from value
$value = trim($value);
if(empty($value)) {
echo 'User credentials have not been set'; // for testing purposes
return FALSE;
}
}
}
private function validate_token_retreived() {
$result = FALSE;
// Bool value not sure if this is the best way to do this
if(isset($this->$token)) {
$result = TRUE;
}
return $result;
}
}
First issue: I need to validate the user parameter which is in an array so I can use with a private method to retrieve the token. I chose to use a foreach loop to check each value but it seems a little archaic.
Second Issue: I have a redundant check in place for each public method to check if token is valid. Is there a better way to do this with OOP? I have many methods that require the token.
In short, how can I make sure that once the class is instantiated a public method that will be used by end user will not fire if any validation fails. The user info only needs to be valid once when instantiated and then the token needs to be valid for most remaining methods.
You don't need to pass $user parameter to retreive_token function. You got it in class scope. Just use $this->user in the function to access it. Also you didn't use it in that function, so why u passed it?
You didn't send true in any function.
There's nothing wrong with for-each but you want to check array_map too. Atleast you're applying a function to every item in array. It can be usefull. ps: seems for-each still faster then array_map
Also you would want to check empty function on which cases it returns false
You can use multiple returns in a function. You dont need to set a variable to do that.
Example
private function validate_token_retreived()
{
if(isset($this->token))
return true;
return false;
}
You couldn't use else in most cases.
Example
public function show_all_events()
{
if($this->validate_token_retreived()) {
// Use token to retreive events list via HTTP request
// and return here
}
echo 'API not active. No valid token detected'; // for testing purposes
return FALSE; // do you really return here? seems you are just generating an output
}
I have read a lot about it but i still don't completely get it.
I may use a library of an existing solution in the future but i want to understand and implement my own system right now.
In order to be stateless and scalable I think i mustn't store user context on server.
The main problem is a conception one, if i understand the system i will succeed to code it
I have tested code found on Internet which i have modified (french website ref : http://blog.nalis.fr/index.php?post/2009/09/28/Securisation-stateless-PHP-avec-un-jeton-de-session-(token)-protection-CSRF-en-PHP).
Can you tell me if it's correct or if i don't get it?
So to create a token i use this function which takes as parameters, the user's data
define('SECRET_KEY', "fakesecretkey");
function createToken($data)
{
/* Create a part of token using secretKey and other stuff */
$tokenGeneric = SECRET_KEY.$_SERVER["SERVER_NAME"]; // It can be 'stronger' of course
/* Encoding token */
$token = hash('sha256', $tokenGeneric.$data);
return array('token' => $token, 'userData' => $data);
}
So a user can authentified himself and receive an array which contains a token (genericPart + his data, encoded), and hisData not encoded :
function auth($login, $password)
{
// we check user. For instance, it's ok, and we get his ID and his role.
$userID = 1;
$userRole = "admin";
// Concatenating data with TIME
$data = time()."_".$userID."-".$userRole;
$token = createToken($data);
echo json_encode($token);
}
Then the user can send me his token + his un-encoded data in order to check :
define('VALIDITY_TIME', 3600);
function checkToken($receivedToken, $receivedData)
{
/* Recreate the generic part of token using secretKey and other stuff */
$tokenGeneric = SECRET_KEY.$_SERVER["SERVER_NAME"];
// We create a token which should match
$token = hash('sha256', $tokenGeneric.$receivedData);
// We check if token is ok !
if ($receivedToken != $token)
{
echo 'wrong Token !';
return false;
}
list($tokenDate, $userData) = explode("_", $receivedData);
// here we compare tokenDate with current time using VALIDITY_TIME to check if the token is expired
// if token expired we return false
// otherwise it's ok and we return a new token
return createToken(time()."#".$userData);
}
$check = checkToken($_GET['token'], $_GET['data']);
if ($check !== false)
echo json_encode(array("secureData" => "Oo")); // And we add the new token for the next request
Am I right?
Sorry for this long message and sorry for my english.
Thanks in advance for your help!
The problem in your code is: You are basing your entire system on $_GET in the original post is based on Cookies.. You should store the token in cookies (based on your original post, instead of using $_GET
By the way; a few tweaks:
list($tokenDate, $userData) = array_pad(explode("_", $receivedData));
In the next code I don't see how you use $login,$password
function auth($login, $password)
{
// we check user. For instance, it's ok, and we get his ID and his role.
$userID = 1;
$userRole = "admin";
// Concatenating data with TIME
$data = time()."_".$userID."-".$userRole;
$token = createToken($data);
echo json_encode($token);
}