How to use temporarySignedRoute() in Laravel? - php

I have this route in the web.php:
Route::get('/email/sent/{email}', function(){
return view('auth.passwords.email_sent');
})->name('forgot-password.email.sent')->middleware(['signed']);
In a controller I am generating a temporary signed route using:
$url = URL::temporarySignedRoute('forgot-password.email.sent', now()->hours(1), ['email' => $email]);
How ever everytime I visit the route it returns 403 Forbidden. But if I use signedRoute():
$url = URL::signedRoute('forgot-password.email.sent', ['email' => $email]);
It works, I think the problem is with the generated timestamps but I am not really sure.
Has anyone encountered this before?

now()->hours(1) sets the date to now except with the hour changed to the number passed, in your case 1, which is not what you want. And because 1 AM happens to be before the current time, the temporary route is already expired when you try to access it and you get a 403 error.
Try now()->addHours(1) instead.
In the future you could try to die & dump or log now()->hours(1) to check what's wrong with the date and time.
https://laravel.com/docs/9.x/helpers#method-now here the now helper is described. \Illuminate\Support\Carbon is instantiated, which wraps Carbon\Carbon, which means you can see the available methods here: https://carbon.nesbot.com/docs/.
You could also use Carbon directly if you wanted.

Related

Laravel Laravel\Socialite\Two\InvalidStateException

I'm trying to add login with social media
I'm using Laravel 7 and socialite for login.
It was working at first but after the first time I'm getting following error:
Laravel\Socialite\Two\InvalidStateException
vendor/laravel/socialite/src/Two/AbstractProvider.php:210
I have read this question Laravel Socialite: InvalidStateException but I couldn't solve the problem.
I would appreciate any help
In my case the same error was caused by adding a reserved word parameter "state" to the ->with() method. I did:
return Socialite::driver('twitch')
->with(['state' => 'randomstate'])
->redirect();
Removing that helped.
I had the same issue, but only when running the application (Laravel 8) on the production host.
The problem was the enforcement of a restrictive Resource Isolation Policy from the provider, which discarded all input parameters for requests having a sec-fetch-site:cross-site header (which is the case of an OAuth2 redirect).
To verify if this is your case, it is enough to check the contents of the Request coming to your endpoint function: if the following code prints an empty array, you probably have to check your web server configurations.
public function socialCallback(Request $request) {
// Those two lines are just for debug, to be removed
print_r($request->all());
exit();
Socialite::driver('google')->user();
}
Here, more informations about sec-fetch-site.

Laravel Exception handler logs also the request

I'm working on a Laravel 5.8 project, and I want to log inside the daily log file the request that has caused the exception, if some exception occurs.
I've tried this in the public function report(Exception $exception)
parent::render(request());
but it doesn't work at all. I've also tried this
\Log::error(json_encode(request()));
But it logs this
local.ERROR: {"attributes":{},"request":{},"query":{},"server":{},"files":{},"cookies":{},"headers":{}}
How should i do it? I need it in order to understand which request has caused that exception, and if it's possible, i need to log also other values, but i think that solved this, i can reuse the code to logs also the others
You can't just json_encode() the entire request as many properties are private/protected and require the use of getters for access. You will need to determine which values are important to you and build an appropriate response.
$response = [
'method' => request()->method(),
'url' => request()->url(),
'full_url' => request()->fullUrl(),
'data' => request()->all(),
];
Then you can pass your response array as a second parameter to the log handler, without needing to use json_encode().
\Log::error('Request details: ', $response);

How and why does the Laravel cookie persist between redirects but setting it in the global cookie variable does not?

So in a recent problem which I was trying to solve I had to authenticate a user from a third party platform and land him/her directly into our dashboard. Ignoring how the authentication works here. The problem is after I authenticate the request I need to modify a cookie 'xyz' before redirecting it to a different route. Now when i tried to do this
setcookie('xyz', 1);
$_COOKIE['xyz'] = 1;
return redirect('/myroute');
would 0 or '' in /myroute Controller method.
But if I add 'xyz' to exceptions of my EncryptCookies middleware of laravel and do
$cookie = cookie('xyz', 1);
return redirect('/myroute')->withCookie($cookie);
That would give me the value of xyz successfully in /myroute Controller method.
What exactly is happening in the later method (the laravel way) and the first way? Its getting pretty confusing because according to what i know cookies can only be queued to be modified but are only modified after the response is returned to the client. Please point me out my mistakes and shed some light.

php auth0 api update app_data

I am trying to use auth0 api for php. I strated with this examples:
enter link description here
Every time when I start I got error that I'm calling non-defined class in dotenv-autoloader (Dotenv::load(__DIR__);). I avoid this and I wrote manually parameter. After that I can create, delete user, change user_metadata, but I can't change app_matadata. Always got same error: {"statusCode":401,"error":"Unauthorized","message":"Missing authentication"}
Can someone help me with this issue?
Thanks.
what error did you get with Dotenv?
3 things might happened:
it was not installed (which is weird since it is a dependency in the
composer.json file)
there was no .env file with the configuration
the .env file had the wrong format
Anyway, if you set the configuration manually is enough.
About the app_metadata how are you updating it?
this snippet should work:
require __DIR__ . '/vendor/autoload.php';
use Auth0\SDK\Auth0Api;
$token = "eyJhbGciO....eyJhdWQiOiI....1ZVDisdL...";
$domain = "account.auth0.com";
$user_id = 'auth0|123...';
$auth0Api = new Auth0Api($token, $domain);
$usersList = $auth0Api->users->update( $user_id, [ "app_metadata" => [ "some_attribute" => "some_value" ] ]);
var_dump($usersList);
One important thing, to update the app_metadata you need an api token with the update:users_app_metadata scope, you can't use the user token for it.

Cannot test redirects when unit testing Laravel 5

Here is my test code:
public function testRegistrationFailsIfNameIsEmpty()
{
$this->flushSession();
$response = $this->call('POST', '/signup', ['fullname' => '']);
$this->assertSessionHasErrors('fullname'); // Passes, expected
$this->assertTrue($response->isRedirection()); // Passes, expected
$this->assertRedirectedTo('/signup'); // Fails, unexpected.
}
When I call that method, it's validating the input, and if the validation fails, it redirects me back to /signup to show the validation errors. I've manually tested this in the browser, and it works as expected.
However, when I run the above unit test, the last assertion fails, and it thinks I've been redirected to just / rather than /signup.
I have no idea why it's doing this. If I test that a redirect happened at all, the test passes because a redirect does happen, it just thinks the redirect is to / instead of /signup.
I've disabled all middleware so I know it's not something like guest middleware thinking I'm logged in when I'm not.
EDIT: Test Results:
There was 1 failure:
1) RegistrationTest::testRegistrationFailsIfNameIsEmpty
Failed asserting that two strings are equal.
--- Expected
+++ Actual
## ##
-'http://localhost/signup'
+'http://localhost'
Using request()->validate() will return you to the calling url if validation fails. When running unit tests, there is no calling page so you will be directed to home.
https://laravel.com/docs/5.5/validation#quick-writing-the-validation-logic
if validation fails, an exception will be thrown and the proper error
response will automatically be sent back to the user. In the case of a
traditional HTTP request, a redirect response will be generated
So you either need to test that your redirect is to home, or fudge the calling url. Though then you're just testing the validator rather than your code, which doesn't really add anything:
session()->setPreviousUrl('/calling/url');
https://www.neontsunami.com/posts/testing-the-redirect-url-in-laravel
Edit:
Actually, this can be useful when the test expects the redirect to go to a route with a named parameter.
Edit for Laravel 5.8:
The test should be called with:
$this->from('/calling/url')
->get('/some/route')
->assertRedirect('/somewhere/else');
I had this same issue when testing a Laravel app. It seems that when you use $this->call in the test and then your controller uses something like Redirect::back(), the redirect is sent to '/'. I believe this is because you weren't on any page when you made "$this->call" so the application is unsure where to redirect you, unless you are explicit about the redirect in the controller, i.e. redirect('somePage').
However when doing something like $this->actingAs($user)->visit('somePage')->press('someButton'), you are correctly sent back to the expected page when using Redirect::back(). Likely because the app knows what page you started on.
You have to set ->from(route('RouteName')) in order to make sure the redirection assertion is properly set
I recommend you to print Response object from controller with dd() when unit testing this single test. This will show you where exactly the redirect is made. Unit test engine just parses the Response object and I believe the problem is in the code rather in the Unit test.
Could you check the test hitting the redirect function in controller
you can put a die in function and find-out where is the error
It should be an issue in method.
then check it actually goes in to the redirect part
for example you want to test a request validation failure. And for example it suppose to redirect your user to a previous url with validation failed exception and some messages. Say, you want to update a customer name.
// --- making a post request ----
$name = 'a new name that is too long';
$route = route('customer.update');
$response = $this
->withSession(['_previous' => ['url' => 'https://google.com']])
->call('POST', $route, [
'_token' => csrf_token(),
'name' => $name,
]);
// --- unit test assertions ----
$response->assertStatus(302);
$response->assertRedirect('https://google.com');
$message = __('#lang_file.some error message text here.');
$expected = [
'default' => ['' => [$message]]
];
$actual = session_errors()->getBags();
$actual = json_encode($actual);
$actual = json_decode($actual, true);
$this->assertSame($expected, $actual);
a function that return session errors:
function session_errors(): ViewErrorBag
{
$key = config('session.keys.errors');
$errors = session()->get($key, app(ViewErrorBag::class));
return $errors;
}

Categories