oriceon/oauth-5-laravel install controller request error - php

This is my first time implementing OAuth to my projects. I found a walkthrough on github for laravel-5 oriceon/oauth-5-laravel. I followed all the steps correctly. However when I get to the controller function I get an error saying:
Call to undefined method Illuminate\Support\Facades\Request::get()
Here is my controller function:
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'), true);
$message = 'Your unique facebook user id is: ' . $result['id'] . ' and your name is ' . $result['name'];
echo $message. "<br/>";
//Var_dump
//display whole array.
dd($result);
}
// if not ask for permission first
else
{
// get fb authorization
$url = $fb->getAuthorizationUri();
// return to facebook login url
return redirect((string)$url);
}
}
In the app you can see that i did add the correct provider and alias:
'OAuth' => Artdarek\OAuth\Facade\OAuth::class,
Artdarek\OAuth\OAuthServiceProvider::class,
In my view I call the route that leads to the correct controller function and I keep arriving to this error. What could it be that does this? Should the function be calling to the provider or something? Thanks for looking at this Stack!

First up, I hope your view isn't calling a route- that's backwards. Routes are used immediately to determine the controller, which is then used to determine and respond with the proper view.
... That aside, Request is the name of a facade in Laravel. That's why the error message says it's looking for the get() method on the Illuminate\Support\Facades\Request class. You'll want to namespace the Request class you're using so that it's able to use the correct get() method. Depending on your version, I do this with use Illuminate\Http\Request; at the top of my controller file (immediately after the namespace declaration for the controller).

Related

Laravel Oauth2 controller using League OAuth2 client

I'm trying to use the League OAuth2 Client to allow users to authenticate my Laravel web app to set appointments on their calendar. NOTE: I'm not trying to let users login to my site or authenticate into my site using OAuth! I just want to be able to let users add appointments to their own calendars.
I'm basically following the flow outlined here: https://github.com/thephpleague/oauth2-google and have created a single controller (called OauthController with a single method, redirectGoogle. My redirect route (which is registered with Google) is https://example.com/oauth2/google. When I hit this endpoint in my Laravel app, I get redirected to Google to approve my app to access my account data as expected, and then redirected back to the controller endpoint.
However it fails every time at the exit('Invalid state'); line.
Here's the controller method code:
public function redirectGoogle(Request $request)
{
$provider = new Google([
'clientId' => config('oauth.google_oauth_id'),
'clientSecret' => config('oauth.google_oauth_secret'),
'redirectUri' => 'https://example.com/oauth2/google',
]);
if (!empty($request->input('error'))) {
// Got an error, probably user denied access
dd($request->input('error'));
} elseif (empty($request->input('code'))) {
// If we don't have an authorization code then get one
$authUrl = $provider->getAuthorizationUrl();
session(['oauth2state', $provider->getState()]);
Log::info('Storing provider state ' . session('oauth2state')); <-- Log entry exists so we know session value was written
header('Location: ' . $authUrl);
exit;
} elseif (empty($request->input('state')) || ($request->input('state') !== session('oauth2state', false))) {
Log::error($request->input('state') . ' did not equal stored value ' . session('oauth2state', false)); <-- Log entry exists
// State is invalid, possible CSRF attack in progress
exit('Invalid state'); <-- Breaks here
} else {
// Try to get an access token (using the authorization code grant)
$token = $provider->getAccessToken('authorization_code', [
'code' => $request->input('code')
]);
// Optional: Now you have a token you can look up a users profile data
try {
// We got an access token, let's now get the owner details
$ownerDetails = $provider->getResourceOwner($token);
// Use these details to create a new profile
dd('Hello %s!', $ownerDetails->getFirstName());
} catch (Exception $e) {
// Failed to get user details
dd('Something went wrong: ' . $e->getMessage());
}
// Use this to interact with an API on the users behalf
echo $token->getToken() . PHP_EOL;
// Use this to get a new access token if the old one expires
echo $token->getRefreshToken() . PHP_EOL;
// Unix timestamp at which the access token expires
echo $token->getExpires() . PHP_EOL;
dd();
}
}
The strange thing is that the log messages noted in the code above both exist, and the values match (at least, it is attempting to write the first session variable with a value that would match the second log file's value):
[2020-05-04 21:02:48] local.INFO: Storing provider state 4963a33bbd5bcf52d3e21c787f24bd7b
[2020-05-04 21:02:51] local.ERROR: 4963a33bbd5bcf52d3e21c787f24bd7b did not equal stored value <null>
Why is it that the second time through the code the oauth2state session value is null, when it was successfully written on the first loop?
NOTE: the problem appears to be that the sessions are different, which makes sense, but how can this session stay consistent, or otherwise keep the data straight?
[2020-05-05 15:25:06] local.INFO: Session id: bV7F5mNM69rJAVJNWK9ZD0rcoN284FxXvjNAmUiw
[2020-05-05 15:25:06] local.INFO: Storing provider state 7351b313b741df41a6be9a049f71db6b
[2020-05-05 15:25:10] local.INFO: Session id: VNiBxr1gYYIA9Nr11x9c4JJArHOiKQScEGh2jkuc
[2020-05-05 15:25:10] local.ERROR: 7351b313b741df41a6be9a049f71db6b did not equal stored value <null>
EDIT2: I've tried the tutorial here which uses a slightly different approach using Laravel and the League Oauth library-- it has the exact same problem, the session ID is different between the two requests, meaning there's no way you'll ever get a match between the state keys.
I believe the problem lies with how you redirect to google.
Problem:
Laravel needs to run trough the whole request in order to persist values into the session.
By using exit; you are interrupting the request and therefore Laravel will not get the chance to persist the values into the session.
Solution:
By using the redirect() helper as suggested in the docs, Laravel will be able to complete the request.
elseif(empty($request->input('code'))) {
// If we don't have an authorization code then get one
$authUrl = $provider->getAuthorizationUrl();
session(['oauth2state', $provider->getState()]);
Log::info('Storing provider state ' . session('oauth2state'));
return redirect($authUrl);
}
Explanation:
In Laravel you can decide when a middleware is run, from the docs:
Before & After Middleware
Whether a middleware runs before or after a request depends on the
middleware itself. For example, the following middleware would perform
some task before the request is handled by the application:
public function handle($request, Closure $next)
{
// Perform action
return $next($request);
}
However, this middleware would perform its task after the request is
handled by the application:
public function handle($request, Closure $next)
{
$response = $next($request);
// Perform action
return $response;
}
Now if we take a look at how Laravel persists the session data in the StartSession middleware, you can see here that Laravel tries to persist the data into the session after the request has been handled by the application, so by using exit;, die(); or dd(); your are stopping the script and Laravel never gets the opportunity to persist the values in the session.
protected function handleStatefulRequest(Request $request, $session, Closure $next)
{
// Before middleware
$request->setLaravelSession(
$this->startSession($request, $session)
);
$this->collectGarbage($session);
$response = $next($request);
// After middleware
$this->storeCurrentUrl($request, $session);
$this->addCookieToResponse($response, $session);
$this->saveSession($request);
return $response;
}

Php add new headers to the current request

i have two methods:
method one catch the username and password
method 2 is a service that should catch the username and password through custom request headers
i want to add the username and password as custom headers to the current request so method 2 can handle them
method 2 has one parameter which is IRequest
i'm using OwnCloud, trying to make a plugin app to control Authentication, this works when calling OwnCloud through webdav in C# but i need it to control OwnCloud login page also by catching userName and password and use the same code in the module object
how can add new headers to the current request call since the header("..") function not working?
class Application extends App {
public function pre_login($parameters) { // method 1
$uid = $parameters['uid'];
$password = $parameters['password'];
header("UserId:" . $uid);
header("Password:" . $password);
}
}
class AuthModule implements IAuthModule {
public function auth(IRequest $request) { // method 2
$UserId = $request->getHeader('UserId'); // not working
$password= $request->getHeader('password'); // not working
}
}
If you have 2 different apps and want to get headers (on your api for example) take into account that some frameworks add additional info to headers. Try getHeader('HTTP_UserId')

Laravel5.4: How to mock the current page?

I want to test a helper function using Request::fullUrl in it.
function foo($arg)
{
// Get current full URL.
$url = Request::fullUrl();
// Return modified URL.
return $url;
}
The docs says:
You should not mock the Request facade. Instead, pass the input you desire into the HTTP helper methods such as get and post when running your test.
What are "the HTTP helper methods"?
They mean "TestCase::get" and "TestCase::post"?
Yes, my problem was solved by using $this->get().
But is this correct way?
class MyHelperTest extends TestCase
{
public function testFoo()
{
// Move to index page.
$this->get('/');
// Get a modified URL.
$url = foo('arg');
$this->assertEquals('Expected URL', $url);
}
}
It solved.
Using $this->get('/') is correct way.
https://laravel.com/docs/5.4/http-tests
The get method makes a GET request into the application

{"status":false,"error":"Unknown method"} error CodeIgniter RESTful API

<?php
include(APPPATH.'/libraries/REST_Controller.php');
class Quiz extends REST_Controller{
function __construct()
{
// Call the Model constructor
parent::__construct();
}
public function user_get()
{
$this->load->model('Quizmodel');
$data = $this->Quizmodel->getAll();
$this->response($data, 200);
}
function restclient()
{
$this->load->library('rest', array(
'server' => 'http://localhost/CodeIg/index.php/quiz/'
));
$userr = $this->rest->get('user','','json');
echo $userr;
}
}
?>
I am able to get JSON output if I type http://localhost/CodeIg/index.php/quiz/user in my browser, however if I type http://localhost/CodeIg/index.php/quiz/restclient it gives this error: {"status":false,"error":"Unknown method"}
I tried changing get to post but still the same error.
I referred this page https://code.tutsplus.com/tutorials/working-with-restful-services-in-codeigniter--net-8814 to do it.
You pinged me on GitHub, even though I haven't used or even thought about this code in at least 4 years.
https://github.com/chriskacerguis/codeigniter-restserver/blob/d19dc77f03521c7a725a4555407e1e4e7a85f6e1/application/libraries/REST_Controller.php#L680
This is where that error is being triggered. Throw a few breakpoints in there or var_dump()'s until you see what is causing the trouble.
You probably want to get off CodeIgniter though, and use something more actively maintained like SlimPHP or Lumen.
firstly I want as you have loaded rest api and created your controller quiz as an api to call , where you can only create your functions like user_get or restclient_get and access them the same manner you are doing.Just change you function name restclient to restclient_get then it will call instead it is even not running at this moment.

How to deal with "Request denied by Throttle server" SOAP responses in Laravel 5

I have made a web application that uses SOAP exchanges to get data from a Web API. This was initially done in a procedural way and I'm now trying to move it into a Laravel framework. I have a view set up to display to the user if the SOAP Response is "Request denied by Throttle server" but I don't know how to check for that particular error. Here is the Class:
<?php namespace App\Models;
use SoapClient;
use Illuminate\Http\RedirectResponse;
class SoapWrapper {
public function soapExchange() {
// set WSDL for authentication and create new SOAP client
$auth_url = "http://search.webofknowledge.com/esti/wokmws/ws/WOKMWSAuthenticate?wsdl";
// set WSDL for search and create new SOAP client
$search_url = "http://search.webofknowledge.com/esti/wokmws/ws/WokSearch?wsdl";
// array options are temporary and used to track request & response data
$auth_client = #new SoapClient($auth_url);
// array options are temporary and used to track request & response data
$search_client = #new SoapClient($search_url);
// run 'authenticate' method and store as variable
$auth_response = $auth_client->authenticate();
// call 'setCookie' method on '$search_client' storing SID (Session ID) as the response (value) given from the 'authenticate' method
// check if an SID has been set, if not it means Throttle server has stopped the query, therefore display error message
if (isset($auth_response->return)) {
$search_client->__setCookie('SID',$auth_response->return);
} else {
return Redirect::route('throttle');
}
}
}
The problem is that it throws the "Request denied by Throttle server" default Laravel error at $auth_response = $auth_client->authenticate(); before it gets to the if statement that checks if a value (SessionID) has been returned by the SOAP Request. It didn't do this when it was set up in a procedural way for some reason.
The if statement checks if a value has been returned from the authenticate() method and if it has, assigns it (SessionID) to the cookie of the search client to authorise searches. Otherwise it displays a custom error message.
I have tried using is_soap_fault but that doesn't catch it because it isn't technically a soap fault. I've also tried removing the line causing the problem and changing the if statement to:
if (isset($auth_client->authenticate()->return) {...
But that just causes the default Laravel SoapFault page too. The return Redirect::route('throttle') displays a custom error page to the user, saved as throttle.blade.php.
Anyone know how I can test for the throttle error?
Never mind, found answer here: Catching an exception when creating a new SoapClient properly.
I'll post my amended code anyway just in case it's of any use to anyone else in future:
<?php namespace App\Models;
use SoapClient;
use Illuminate\Http\RedirectResponse;
class SoapWrapper {
public function soapExchange() {
try {
// set WSDL for authentication and create new SOAP client
$auth_url = "http://search.webofknowledge.com/esti/wokmws/ws/WOKMWSAuthenticate?wsdl";
// set WSDL for search and create new SOAP client
$search_url = "http://search.webofknowledge.com/esti/wokmws/ws/WokSearch?wsdl";
// array options are temporary and used to track request & response data
$auth_client = #new SoapClient($auth_url);
// array options are temporary and used to track request & response data
$search_client = #new SoapClient($search_url);
// run 'authenticate' method and store as variable
$auth_response = $auth_client->authenticate();
// add SID (SessionID) returned from authenticate() to cookie of search client
$search_client->__setCookie('SID', $auth_response->return);
} catch (\SoapFault $e) {
return Redirect::route('throttle');
}
}
}

Categories