Problem with Laravel, GuzzleHttp Request and Cloud9 - php

I am trying to implement GuzzleHttp Application in my React/Laravel App.
This is my Routes:
This is my Controller Code:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class AuthController extends Controller
{
public function login(Request $request){
$http = new \GuzzleHttp\Client;
try {
$response = $http->post(route('passport.token'), [
'form_params' => [
'grant_type' => 'password',
'client_id' => config('gocv.passport.client_id'),
'client_secret' => config('gocv.passport.client_secret'),
'username' => $request->username,
'password' => $request->password,
],
'headers' => [
// 'User-Agent' => 'testing/1.0',
'Accept' => 'application/json'
]
]);
return $response->getBody();
} catch (\GuzzleHttp\Exception\BadResponseException $e) {
if($e->getCode() == 400)
{
return response()->json('Invalid Request. Please Eneter username and password', $e->getCode());
}
else if($e->getCode() == 401)
{
return response()->json('Invalid Credentials', $e->getCode());
}
return response()->json('Something Went Wrong', $e->getCode());
}
}
}
This is my Postman Request:
When I am trying to do Post Request on this route: (api/login) it does not return any response. server just stops working and I need to restart it.
Enviroment is AWS Cloud9, php version 7.2 and laravel version 5.7 running with only php artisan serve --port=8082 --host=0.0.0.0
Note: when I send get request on other site ex: github.com it returns response. the problem is when I am trying to do request on same IP.
PS. when I try to login on route /oauth/token it works and returns token
Any answer will be apreciated . Thanks.

Related

Laravel Passport POST oauth/token resulted in a '404 Not Found' when make refresh token

I'm using an apache virtualhost: 'gradez.loc', each time I try to access the /oauth/token route with cURL or Postman it returns a 404.
When I use php artisan serve and try to access to route via http://localhost:8000 there is no problem and I get back the access and refesh token.
What I have done already:
ran php artisan route:list I can see it returns all the passport routes correctly,
ran php artisan route:cache and php artisan route:clear
ran php artisan optimize
None of these seem to fix the problem unfortunately. I see a lot of people struggling with the same problem, but there's no good answer to this.
public function boot()
{
$this->registerPolicies();
if (! $this->app->routesAreCached()) {
Passport::routes();
}
Passport::tokensExpireIn(Carbon::now()->addDays(1));
Passport::refreshTokensExpireIn(Carbon::now()->addDays(10));
Gate::before(function ($user) {
if ($user->isSuperUser()) return true;
});
}
requestAccessToken method:
public function getTokenAndRefreshToken(string $email, string $password)
{
$Oclient = $this->getOClient();
$formParams = ['grant_type' => 'password',
'client_id' => $Oclient->id,
'client_secret' => $Oclient->secret,
'username' => $email,
'password' => $password,
'scope' => '*'];
return $this->sendRequest("/oauth/token", $formParams);
}
public function sendRequest(string $route, array $formParams)
{
try {
$url = self::BASE_URL . $route;
$response = $this->http->request('POST', $url, ['form_params' => $formParams]);
$statusCode = 200;
$data = json_decode((string)$response->getBody(), true);
} catch (ClientException $e) {
echo $e->getMessage();
$statusCode = $e->getCode();
$data = ['error' => 'OAuth client error'];
}
return ["data" => $data, "statusCode" => $statusCode];
}
public function getOClient()
{
return OClient::where('password_client', 1)->first();
}
and my reponse is :
Client error: `POST http://localhost/oauth/token` resulted in a `404 Not Found` response:
Not Found (truncated...)
array:2 [
"data" => array:1 [
"error" => "OAuth client error"
]
"statusCode" => 404
]

Laravel: Target [Lcobucci\JWT\Parser] is not instantiable

Hey I am having an issue on my prod website trying to log in with Laravel passport. It says my Lcobucci JWT Parser is not instantiable. It works for me locally but not on my remote.
How can I resolve this?
Error:
exception: "Illuminate\Contracts\Container\BindingResolutionException"
file: "/var/www/html/vendor/laravel/framework/src/Illuminate/Container/Container.php"
line: 1038
message: "Target [Lcobucci\JWT\Parser] is not instantiable while building [Laravel\Passport\PersonalAccessTokenFactory]."
trace: [,…]
Login Controller Method:
public function login(Request $request) {
$login = $request->validate([
'email' => 'required:string',
'password' => 'required:string'
]);
if(filter_var($request->email, FILTER_VALIDATE_EMAIL)) {
//user sent their email
Auth::attempt(['email' => $request->email, 'password' => $request->password]);
} else {
//they sent their username instead
Auth::attempt(['username' => $request->email, 'password' => $request->password]);
}
if(!Auth::check()) {
return response([
'status' => 'fail',
'message' => 'Invalid credentials'
]);
}
$accessToken = Auth::user()
->createToken('authToken')
->accessToken;
return response([
'status' => 'success',
'user' => new User_Resource(Auth::user()),
'access_token' => $accessToken
]);
}
I encountered the same issue as well, in your project composer.json add "lcobucci/jwt": "3.3.3" and execute composer update.
I found this solution on: https://github.com/laravel/passport/issues/1381.
Laravel : "8" and Lcobucci\JWT : "^3.4"
Solution:
use Lcobucci\JWT\Encoding\JoseEncoder;
use Lcobucci\JWT\Token\Parser;
.
.
...
public function GetTokenId(Request $request)
{
// Get the Access_Token from the request
$Token = $request->bearerToken();
// Parse the Access_Token to get the claims from them the jti(Json Token Id)
$TokenId = (new Parser(new JoseEncoder()))->parse($token)->claims()
->all()['jti'];
return $tokenId;
}
if anyone still getting this error that's because $verifiedIdToken->getClaim('sub') has been deprecated in 3.4 and removed in 4.0.
use $verifiedIdToken->claims()->get('sub') this insted.

Laravel cURL error 6: Could not resolve host: oauth

I get this error on Digital Ocean Ubuntu server after deployment. It works perfectly on Heroku which is our staging server. It is a Laravel project where we use Laravel Passport. How do we solve this?
<?php
namespace App\Http\Traits;
use Illuminate\Support\Facades\Http;
use Laravel\Passport\Client as AuthClient;
use Exception;
trait AuthTrait
{
public function getTokenAndRefreshToken($email, $password)
{
try {
$auth_client = AuthClient::where('password_client', 1)->first();
$url = env('APP_URL') . "/oauth/token";
$response = Http::asForm()->post($url, [
'grant_type' => 'password',
'client_id' => $auth_client->id,
'client_secret' => $auth_client->secret,
'username' => $email,
'password' => $password,
'scope' => '*'
]);
$result = json_decode((string) $response->getBody(), true);
return $result;
} catch (Exception $e) {
throw $e;
}
}
}

Can't get token and user data at the same time while using Vue.js and laravel/passport and GuzzleHttp

I cannot get the user data and bearer token at the same time. Using vue 2.5 and laravel 7.2.2
I am using GuzzleHttp to make a request to the server in order to get the token.
In order to the request to go through I run a second php artisan serve --port 8006 command.
User exists in the database - have verified.
My AuthController:
use App\User;
use App\Shop;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use \GuzzleHttp\Client;
use DB;
public function login(Request $request)
{
$user = User::where('email', $request->email)->get();
$client = new Client([
'base_uri' => 'http://127.0.0.1:8006',
'timeout' => 5
]);
try {
$response = $client->request('POST', 'oauth/token', [
'form_params' => [
'grant_type' => 'password',
'client_id' => 2,
'client_secret' => DB::table('oauth_clients')->where('id', 2)->first()->secret,
'username' => $request->email,
'password' => $request->password,
]
]);
$user->token = $response->getBody();
return $user;
} catch (\GuzzleHttp\Exception\BadResponseException $e) {
if ($e->getCode() === 400 || $e->getCode() == 401) {
return response()->json(['message' => 'Грешно потребителко име или парола'], $e->getCode());
}
return response()->json('Something went wrong on the server.', $e->getCode());
}
}
The response is:
[
{
"id": 1,
"name": "Nelly",
"email": "n#n.com",
"email_verified_at": null,
"created_at": "2020-04-05T11:18:30.000000Z",
"updated_at": "2020-04-05T11:18:30.000000Z"
}
]
If I make the method to return $response->getBody() I get the bearer token only.
If I make the method to return $user I get the user only
Tried using GuzzleHttp\Promise\Promise as follows:
public function login(Request $request)
{
$user = User::where('email', $request->email)->get();
$client = new Client([
'base_uri' => 'http://127.0.0.1:8006',
'timeout' => 5
]);
try {
$promise = $client->requestAsync('POST', 'oauth/token', [
'form_params' => [
'grant_type' => 'password',
'client_id' => 2,
'client_secret' => DB::table('oauth_clients')->where('id', 2)->first()->secret,
'username' => $request->email,
'password' => $request->password,
]
]);
$promise->then(
// $onFulfilled
function ($value) {
dd('The promise was fulfilled.');
},
// $onRejected
function ($reason) {
dd('The promise was rejected.');
}
);
dd('outside of the then');
}
}
Every attempt returns "outside of the then"
So basically you are sending an http request to yourself to get logged in. why don't you just do a normal check and create access token manually
I know this is not guzzle but I thought it might be helpful
Source
if (! Auth::attempt($request->only(['email', 'password']))) {
throw new \Exception('User not found');
}
/** #var User $user */
$user = Auth::user();
$token = $user->createToken('Token Name')->accessToken;;
dd($token);

Guzzle POST request to JWT API get Unauthorized while Postman is working

Guzzle POST request to JWT API get Unauthorized while Postman is working.
Here is the code:
public function __construct()
{
$this->client = new Client();
$this->connect();
}
public function connect()
{
$loginResult = $this->client->request('POST', config('api.base_uri') .'/auth/login', [
'form_params' => [
'email' => config('api.login'),
'password' => config('api.password'),
]
]);
dd(json_decode($loginResult->getBody()));
}
I got 401 Unauthorized while running this code. Credentials are passed correctly.
Meanwhile in Postman it is working perfectly:
Kindly advise me what I'm doing wrong.
Thanks!
UPDATE
Following is controller and function this request is hitting in API side:
class AuthController extends Controller
{
public function __construct()
{
$this->middleware('auth:api', ['except' => ['login']]);
}
public function login(Request $request)
{
$credentials = $request->only(['email', 'password']);
if (!$token = auth('api')->attempt($credentials)) {
return response()->json(['error' => 'Unauthorized '.$credentials['email']], 401);
}
return $this->respondWithToken($token);
}
...
User does exist as it is working in Postman
UPDATE 2
I have simplified code to find that is wrong to:
Route::get('/guzzle', function () {
$client = new Client([
'headers' => [
'Accept' => 'application/json'
]]);
$loginResult =
$client->request('POST', config('pics.base_uri') .'/auth/login', [
'form_params' => [
'email' => '****#****.com',
'password' => '*****',
]
]);
dd(json_decode($loginResult->getBody()));
});
And it does not work - got same error
Okay... after couple of hours and kind help of Kyslik I was able to find the clue of this issue. Actually what did helped me is debugging and looking up the error I get. Eventually I found following post (https://github.com/guzzle/guzzle/issues/1413#issuecomment-222031665) which states kind of strange thing:
Guzzle won't work at all if the same instance of PHP is used to send the Request from Guzzle, and to respond that request
I moved everything to hosting and it worked like a charm. Hope that will help someone in future.
Thanks everyone who envolved finding solution and of course to Kyslik!
Try using the json option in the Guzzle options in your POST request instead of the form_params.
public function connect()
{
$loginResult = $this->client->request('POST', config('api.base_uri') .'/auth/login', [
'json' => [
'email' => config('api.login'),
'password' => config('api.password'),
]
]);
dd(json_decode($loginResult->getBody()));
}
form_params should be used with non-json endpoints.
More information on the json property: http://docs.guzzlephp.org/en/stable/quickstart.html#uploading-data
EDIT an example for an endpoint that accepts form-params but returns JSON, which might be what you have:
public function __construct()
{
$this->client = new Client()
$this->connect();
}
public function connect()
{
$loginResult = $this->client->request('POST', config('api.base_uri') .'/auth/login', [
'form_params' => [
'email' => config('api.login'),
'password' => config('api.password'),
]
]);
dd(json_decode($loginResult->getBody()));
}
Run php artisan config:cache on both sites to solve this problem.
Two sites on Apache on Windows requires cached configurations. It's a known but non-documented problem. Run php artisan config:cache on both sites.
Src: https://github.com/laravel/framework/issues/21533#issuecomment-334352170

Categories