Laravel 5 create middleware with oauth2 server check - laravel

I have implemented this oauth server http://bshaffer.github.io/oauth2-server-php-docs/
It has a Laravel implementation : http://bshaffer.github.io/oauth2-server-php-docs/cookbook/laravel/
This guide you and gives that code for routes :
App::singleton('oauth2', function() {
$storage = new OAuth2\Storage\Pdo(array('dsn' => 'mysql:dbname=oauth2;host=localhost', 'username' => 'root', 'password' => 'root'));
$server = new OAuth2\Server($storage);
$server->addGrantType(new OAuth2\GrantType\ClientCredentials($storage));
$server->addGrantType(new OAuth2\GrantType\UserCredentials($storage));
return $server;
});
Route::get('private', function()
{
$bridgedRequest = OAuth2\HttpFoundationBridge\Request::createFromRequest(Request::instance());
$bridgedResponse = new OAuth2\HttpFoundationBridge\Response();
// fix for laravel
$bridgedRequest->request = new \Symfony\Component\HttpFoundation\ParameterBag();
$rawHeaders = getallheaders();
if (isset($rawHeaders["Authorization"])) {
$authorizationHeader = $rawHeaders["Authorization"];
$bridgedRequest->headers->add([ 'Authorization' => $authorizationHeader]);
}
if (App::make('oauth2')->verifyResourceRequest($bridgedRequest, $bridgedResponse)) {
$token = App::make('oauth2')->getAccessTokenData($bridgedRequest);
return Response::json(array(
'private' => 'stuff',
'user_id' => $token['user_id'],
'client' => $token['client_id'],
'expires' => $token['expires'],
));
}
else {
return Response::json(array(
'error' => 'Unauthorized'
), $bridgedResponse->getStatusCode());
}
});
It works perfectly well like that. Now I want to transform that check function in the "private" route to a middleware I could apply to each necessary route. I created the middleware using
php artisan make:middleware AuthChecker
Added it to the kernel.php, and pasted the code of the verification function inside of it. And I immediately got an error :
FatalErrorException in AuthChecker.php line 17:
Class 'Oauth2\HttpFoundationBridge\Request' not found
So, I guess I will have to "use" things, but since I'm still a beginner I don't really know what to do...
Thanks ahead for your help !
[EDIT] the content of the middleware currently look like this :
namespace App\Http\Middleware;
use Closure;
class OauthCheck {
public function handle($request, Closure $next)
{
$bridgedRequest = OAuth2\HttpFoundationBridge\Request::createFromRequest($request);
$bridgedResponse = new OAuth2\HttpFoundationBridge\Response();
// fix for laravel
$bridgedRequest->request = new \Symfony\Component\HttpFoundation\ParameterBag();
$rawHeaders = getallheaders();
if (isset($rawHeaders["Authorization"])) {
$authorizationHeader = $rawHeaders["Authorization"];
$bridgedRequest->headers->add([ 'Authorization' => $authorizationHeader]);
}
if (App::make('oauth2')->verifyResourceRequest($bridgedRequest, $bridgedResponse)) {
$token = App::make('oauth2')->getAccessTokenData($bridgedRequest);
return Response::json(array(
'private' => 'stuff',
'user_id' => $token['user_id'],
'client' => $token['client_id'],
'expires' => $token['expires'],
));
return $next($request);
}
else {
return Response::json(array(
'error' => 'Unauthorized'
), $bridgedResponse->getStatusCode());
}
}
}
Thanks again

FatalErrorException in AuthChecker.php line 17:
Class 'Oauth2\HttpFoundationBridge\Request' not found
So you want to use the Request class from Oauth2\HttpFoundationBridge namespace to your OauthCheck class from App\Http\Middleware.
You can do it in either ways:
Import the class
namespace App\Http\Middleware;
use Oauth2\HttpFoundationBridge\Request;
class OauthCheck {
public function handle($request, Closure $next)
{
$bridgedRequest = Request::createFromRequest($request);
....
}
}
Use the class explicitly
namespace App\Http\Middleware;
class OauthCheck {
public function handle($request, Closure $next)
{
$bridgedRequest = \Oauth2\HttpFoundationBridge\Request::createFromRequest($request);
....
}
}
Take note of the backslash before Oauth2\HttpFoundationBridge\Request. If you just say $bridgedRequest = Oauth2\HttpFoundationBridge\Request, then PHP will look for App\Http\Middleware\Oauth2\HttpFoundationBridge\Request.

Related

how to use reflash or more session to transport session

in my controllers at laravel 9 **postManageTwoFactor** method i use $request->session()->flash('phone2' , $data['phone']);
for transport session to method **getPhoneVerify** , this is ture!
then i use $request->session()->reflash(); when i want to "reflash session " to postPhoneVerify method for last time, this is null or false!
i need this session $request->session()->get('phone2') in postPhoneVerify method...\
thank for helping me
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\ActiveCode;
class ProfileController extends Controller
{
public function index()
{
return view('profile.index');
}
public function manageTwoFactor()
{
return view('profile.two-factor-auth');
}
public function postManageTwoFactor(Request $request)
{
$data = $request->validate([
'type' => 'required|in:on,off',
'phone' => 'required_unless:type,off',
]);
if($data['type'] === 'on'){
if($request->user()->phone_number !== $data['phone']){
/*create the new code for users...*/
$code = ActiveCode::generateCode($request->user());
/*
* in sessions "flash" meaning:
* validate unitl one route and not any more....
* easy: $data['phone'] store in 'phone2'/
*/
$request->session()->flash('phone2' , $data['phone']);
/*-------- send the code number to phone-----------*/
//TODO send sms for 2auth...
return redirect(route('prof.two.phone'));
}else{
/*
* put that 'on' becuse the number that entered is the same
*/
$request->user()->update([
'two_factor' => 'on'
]);
}
}
if($data['type'] === 'off'){
$request->user()->update([
'two_factor' => 'off'
]);
}
return back();
}
/*
* when this method or route , should be ruunig where users Request
* the code and fill the phone number field...
*/
public function getPhoneVerify(Request $request)
{
if (! $request->session()->has('phone2')){
return redirect(route('profile.2fa'));
}
$request->session()->reflash();
return view('profile.phone-verify');
}
public function postPhoneVerify(Request $request)
{
$request->validate([
'token' => 'required'
]);
if (! $request->session()->has('phone2')){
return redirect(route('profile.2fa'));
}
$status = ActiveCode::verifyCode($request->token , $request->user());
if($status){
/*---- after verify Code we need delete old record for each row user in active_codes table in dbase ---*/
$request->user()->activeCode()->delete();
/*--after all, with under code we can UPDATE active_codes table in database...*/
$request->user()->update([
'phone_number' => $request->session()->get('phone2'),
'two_factor' => 'on'
]);
alert()->success('احراز هویت دو مرحله ای شما انجام شد' , 'عملیات موفق آمیز بود');
}else{
alert()->success('لطفا دوباره تلاش کنید','عملیات موفق آمیز نبود');
}
return redirect(route('profile.2fa'));
}
}

laravel 8 passing data to redirect url

i have store function for save data to database and i want redirect to another url with passing $invoice variable
this is my store function :
$order = Order::create([
'no' => $invoice,
'spg' => $request->spg,
'nama' => $request->nama,
'hp' => $request->hp,
'alamat' => $request->alamat,
]);
return redirect('invoicelink', compact('invoice'));
this is my route file:
Route::resource('/', OrderController::class);
Route::get('invoicelink/{invoice}', [OrderController::class, 'invoicelink'])->name('invoicelink');
and this is my invoicelink function:
public function invoicelink($invoice)
{
dd($invoice);
}
How to do it? very grateful if someone help to solve my problem. thanks
If you look at the helper function you are calling, I don't think it is what you are looking for.
function redirect($to = null, $status = 302, $headers = [], $secure = null)
{
if (is_null($to)) {
return app('redirect');
}
return app('redirect')->to($to, $status, $headers, $secure);
}
I think what you want is
Redirect::route('invoiceLink', $invoice);
You can also use the redirect function, but it would look like this
redirect()->route('invoiceLink', $invoice);
You can see this documented here https://laravel.com/docs/8.x/responses#redirecting-named-routes
i found the solution:
web.php
Route::get('invoicelink/{invoice}', [OrderController::class, 'invoicelink'])->name('invoicelink');
controller:
public function invoicelink($invoice)
{
//dd($invoice);
return $invoice;
}
then use redirect:
return redirect()->route('invoicelink', [$invoice]);

With StripeClient I got error No API key provided

in my Laravel 8 / with stripe/stripe-php": "^7.75" I try to connect and create account on stripe side
and got error :
No API key provided. Set your API key when constructing the StripeClient instance, or provide it on a per-request basis using the `api_key` key in the $opts argument.
with code:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Session;
use Stripe;
use Stripe\StripeClient;
use App\Http\Controllers\Controller;
use Illuminate\Database\DatabaseManager;
use App\Models\Settings;
use Carbon\Carbon;
use Illuminate\Support\Arr;
use App\Models\User;
use App\Models\StripeToken;
class SellerController extends Controller
{
protected StripeClient $stripeClient;
protected DatabaseManager $databaseManager;
public function __construct(StripeClient $stripeClient, DatabaseManager $databaseManager)
{
\Log::info(varDump($stripeClient, ' -1 SellerController ::'));
$this->stripeClient = $stripeClient;
$this->databaseManager = $databaseManager;
}
public function showProfile($id)
{
\Log::info('-1 showProfile $id ::' . print_r($id, true));
$seller = User::find($id);
if (!$seller) {
abort(404);
}
return view('market.seller', [
'seller' => $seller,
'balance' => null
]); // /_wwwroot/lar/tAdsBack/resources/views/admin/stripe/stripe.blade.php
} // public function showProfile($id)
public function redirectToStripe($id)
{
\Log::info('-1 redirectToStripe $id ::' . print_r($id, true));
$seller = User::find($id);
if (!$seller) {
abort(404);
}
$appEnv = strtolower(config('app.env'));
if ($appEnv == 'local' or $appEnv == 'dev') {
\Log::info('-1 config(app.STRIPE_TEST_KEY)::' . print_r(config('app.STRIPE_TEST_KEY'), true));
\Stripe\Stripe::setApiKey(config('app.STRIPE_TEST_KEY')); // LOOKS LIKE THAT IS NOT APPLIED
$this->stripeClient->apiKey = config('app.STRIPE_TEST_KEY'); // THIS DOES NOT HELP
$this->stripeClient->api_key = config('app.STRIPE_TEST_KEY'); // THIS DOES NOT HELP
}
if ($appEnv == 'production') {
\Stripe\Stripe::setApiKey(config('app.STRIPE_LIVE_KEY'));
$this->stripeClient->opts['api_key'] = config('app.STRIPE_LIVE_KEY');
}
if (!$seller->completed_stripe_onboarding) { // Complete onboarding process
$str = \Str::random();
$stripeToken = new StripeToken();
$stripeToken->token = $str;
$stripeToken->seller_id = $id;
$stripeToken->save();
if (empty($seller->stripe_connect_id)) { // if has no stripe account
// // Create a new Stripe Connect Account object.
\Log::info('-1 $$this->stripeClient ::' . print_r($this->stripeClient, true));
Checking log I see :
[2021-03-22 05:40:30] local.INFO: -1 $$this->stripeClient ::Stripe\StripeClient Object
(
[coreServiceFactory:Stripe\StripeClient:private] =>
[config:Stripe\BaseStripeClient:private] => Array
(
[api_key] =>
[client_id] =>
[stripe_account] =>
[stripe_version] =>
[api_base] => https://api.stripe.com
[connect_base] => https://connect.stripe.com
[files_base] => https://files.stripe.com
)
[defaultOpts:Stripe\BaseStripeClient:private] => Stripe\Util\RequestOptions Object
(
[apiKey] =>
[headers] => Array
(
[Stripe-Account] =>
[Stripe-Version] =>
)
[apiBase] =>
)
[api_key] => sk_test_NNNNNN
How to fix this error ?
I suppose I need to set api_key in some other way, not
$this->stripeClient->apiKey = config('app.STRIPE_TEST_KEY'); // THIS DOES NOT HELP
$this->stripeClient->api_key = config('app.STRIPE_TEST_KEY'); // THIS DOES NOT HELP
but how?
Thanks!
Before using stripe/stripe-php directly, check out Laravel Cashier.
https://laravel.com/docs/8.x/billing

How to call API from controller Laravel without using curl and guzzle as its not working [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
How to call an API from a controller using a helper in laravel without using curl and guzzle because both returing nothing. I have tested in postman the api is working fine but not in laravel.
I need to call several API's from different controllers so what would be a good way to do this? Should i build a helper?
I used curl but it is always giving me a false response.
EDIT:
I am looking for a reliable way to make api calls to various url's without having to rewrite the sending and receiving code for each api I want to use.
Preferably a solution that implements "dry" (don't repeat yourself) principles and would serve as a base for any api specific logic, (parsing the response /translating for a model). That stuff would extend this base.
Update For Laravel 7.x and 8.x. Now we can use inbuilt Http(Guzzle HTTP) client.
docs:: https://laravel.com/docs/8.x/http-client#making-requests
use Illuminate\Support\Facades\Http;
$response = Http::get('https://jsonplaceholder.typicode.com/posts');
$response = Http::post('https://jsonplaceholder.typicode.com/posts', [
'title' => 'foo',
'body' => 'bar',
'userId' => 1
]);
$response = Http::withHeaders([
'Authorization' => 'token'
])->post('http://example.com/users', [
'name' => 'Akash'
]);
$response->body() : string;
$response->json() : array|mixed;
$response->object() : object;
$response->collect() : Illuminate\Support\Collection;
$response->status() : int;
$response->ok() : bool;
$response->successful() : bool;
$response->failed() : bool;
$response->serverError() : bool;
$response->clientError() : bool;
$response->header($header) : string;
$response->headers() : array;
For Laravel < 7 you need to install Guzzle pacakge
docs: https://docs.guzzlephp.org/en/stable/index.html
Installation
composer require guzzlehttp/guzzle
GET
$client = new \GuzzleHttp\Client();
$response = $client->get('https://jsonplaceholder.typicode.com/posts');
return $response;
POST
$client = new \GuzzleHttp\Client();
$body = [
'title' => 'foo',
'body' => 'bar',
'userId' => 1
];
$response = $client->post('https://jsonplaceholder.typicode.com/posts', ['form_params' => $body]);
return $response;
Some Usefull Methods
$response->getStatusCode();
$response->getHeaderLine('content-type');
$response->getBody();
we can also add headers
$header = ['Authorization' => 'token'];
$client = new \GuzzleHttp\Client();
$response = $client->get('example.com', ['headers' => $header]);
Helper For this Method
we can create a common helper for these methods.
Create a Helpers folder in app folder
app\Helpers
then create a file Http.php inside Helpers folder
app\Helpers\Http.php
add this code in Http.php
<?php
namespace App\Helpers;
use GuzzleHttp;
class Http
{
public static function get($url)
{
$client = new GuzzleHttp\Client();
$response = $client->get($url);
return $response;
}
public static function post($url,$body) {
$client = new GuzzleHttp\Client();
$response = $client->post($url, ['form_params' => $body]);
return $response;
}
}
Now in controller you can use this helper.
<?php
namespace App\Http\Controllers;
use Illuminate\Routing\Controller as BaseController;
use App\Helpers\Http;
class Controller extends BaseController
{
/* ------------------------ Using Custom Http Helper ------------------------ */
public function getPosts()
{
$data = Http::get('https://jsonplaceholder.typicode.com/posts');
$posts = json_decode($data->getBody()->getContents());
dd($posts);
}
public function addPost()
{
$data = Http::post('https://jsonplaceholder.typicode.com/posts', [
'title' => 'foo',
'body' => 'bar',
'userId' => 1
]);
$post = json_decode($data->getBody()->getContents());
dd($post);
}
}
Without Helper
In Main controller we can create these functions
<?php
namespace App\Http\Controllers;
use Illuminate\Routing\Controller as BaseController;
class Controller extends BaseController
{
public function get($url)
{
$client = new GuzzleHttp\Client();
$response = $client->get($url);
return $response;
}
public function post($url,$body) {
$client = new GuzzleHttp\Client();
$response = $client->post($url, ['form_params' => $body]);
return $response;
}
}
Now in controllers we can call
<?php
namespace App\Http\Controllers;
class PostController extends Controller
{
public function getPosts()
{
$data = $this->get('https://jsonplaceholder.typicode.com/posts');
$posts = json_decode($data->getBody()->getContents());
dd($posts);
}
public function addPost()
{
$data = $this->post('https://jsonplaceholder.typicode.com/posts', [
'title' => 'foo',
'body' => 'bar',
'userId' => 1
]);
$post = json_decode($data->getBody()->getContents());
dd($post);
}
}

Calling the controller i'm in : not found

I'm trying to implement the PayPal API
namespace App\Http\Controllers;
use PayPal;
use Redirect;
class PaypalPaymentController extends Controller{
private $_apiContext;
public function __construct()
{
$this->_apiContext = PayPal::ApiContext(
config('services.paypal.client_id'),
config('services.paypal.secret'));
$this->_apiContext->setConfig(array(
'mode' => 'sandbox',
'service.EndPoint' => 'https://api.sandbox.paypal.com',
'http.ConnectionTimeOut' => 30,
'log.LogEnabled' => true,
'log.FileName' => storage_path('logs/paypal.log'),
'log.LogLevel' => 'FINE'
));
}
public function getCheckout()
{
$payer = PayPal::Payer();
$payer->setPaymentMethod('paypal');
$amount = PayPal:: Amount();
$amount->setCurrency('EUR');
$amount->setTotal(500); // This is the simple way,
// you can alternatively describe everything in the order separately;
// Reference the PayPal PHP REST SDK for details.
$transaction = PayPal::Transaction();
$transaction->setAmount($amount);
$transaction->setDescription('Altaro VM Backup');
$redirectUrls = PayPal:: RedirectUrls();
$redirectUrls->setReturnUrl(action('PaypalPaymentController#getDone'));
$redirectUrls->setCancelUrl(action('PaypalPaymentController#getCancel'));
$payment = PayPal::Payment();
$payment->setIntent('sale');
$payment->setPayer($payer);
$payment->setRedirectUrls($redirectUrls);
$payment->setTransactions(array($transaction));
$response = $payment->create($this->_apiContext);
$redirectUrl = $response->links[1]->href;
return Redirect::to( $redirectUrl );
}
public function getDone(Request $request)
{
$id = $request->get('paymentId');
$token = $request->get('token');
$payer_id = $request->get('PayerID');
$payment = PayPal::getById($id, $this->_apiContext);
$paymentExecution = PayPal::PaymentExecution();
$paymentExecution->setPayerId($payer_id);
$executePayment = $payment->execute($paymentExecution, $this->_apiContext);
// Clear the shopping cart, write to database, send notifications, etc.
// Thank the user for the purchase
return "Merci pour votre achat";
}
public function getCancel()
{
// Curse and humiliate the user for cancelling this most sacred payment (yours)
return "Erreur";
}
}
As you can see in the controller i'm trying to call other function of the controller i'm in :
$redirectUrls->setReturnUrl(action('PaypalPaymentController#getDone'));
$redirectUrls->setCancelUrl(action('PaypalPaymentController#getCancel'));
But i have the following error :
InvalidArgumentException in UrlGenerator.php line 602:
Action App\Http\Controllers\PaypalPaymentController#getDone not defined.
I don't understand how it is even possible... I checked multiple times the spelling, everything's correct here.
Any thoughts ?
EDIT:
I also tried this :
$redirectUrls->setReturnUrl(route('paypal.done'));
$redirectUrls->setCancelUrl(route('paypal.cancel'));
with these routes:
Route::get('done', [
'as' => 'paypal.done',
'uses' => 'PaypalPaymentController#getDone'
]);
Route::get('cancel', [
'as' => 'paypal.cancel',
'uses' => 'PaypalPaymentController#getCancel'
]);
It works !
I think you also have to define a route to the methods, otherwise the URL cannot be build and returns an error.

Resources