Laravel reset password route not working - laravel

I am building custom views to reset passwords.
The routes looks like this:
Route::get('password/reset', 'Auth\ForgotPasswordController#showLinkRequestForm')->name('password.reset');
Route::post('password/email', 'Auth\ForgotPasswordController#sendResetLinkEmail')->name('password.email');
Route::get('password/reset/{token}', 'Auth\ResetPasswordController#showResetForm')->name('password.reset.token');
Route::post('password/reset', 'Auth\ResetPasswordController#reset');
In ResetPasswordController.php I have added this:
//Show form to seller where they can reset password
public function showResetForm(Request $request, $token = null)
{
return view('auth.passwords.reset')->with(
['token' => $token, 'email' => $request->email]
);
}
The link sent to me looks like this:
https://myapp.dev/password/reset?451c70284a9d4b41123c4ec3efe83602b6cb955427ac48835200a45980bcf9f3
If I now enter that link I will go straight to the password/reset view and not the password/reset/{token}
However if I change the link in my broswer to
https://myapp.dev/password/reset/451c70284a9d4b41123c4ec3efe83602b6cb955427ac48835200a45980bcf9f3 (changing "?" to "/") I it works
So why doesnt the ? version of the URL work? I am using laravel 5.5
And since I dotn use the Auth:routes() is there any way to see what routes laravel generates when you use that?

There are two different things with parameters.
Route Parameters: These are included in the routes with '/' as in your example. You can get them by:
$request->parameter('parameter_name');
$request->parameters(); // for all parameters
Request Parameters: These are request parameters which attached in the URL after '?'. Parameters are sent this way in GET request. You can get them by:
$request->input('parameter_name');
$request->all(); // for all parameters

Laravel doc..
Probably you are confused with required parameters and optional parameters.
When you are defining the following route..
Route::get('password/reset/{token}', 'Auth\ResetPasswordController#showResetForm')->name('password.reset.token');
Laravel expects the token value as a required parameter in the third segment of the route.
But when you are accessing the route as
https://myapp.dev/password/reset?451c70284a9d4b41123c4ec3efe8360..
There is only two segment for the route. The token value is assigned as the get parameter or optional parameter.
As you already defined as follows..
Route::get('password/reset', 'Auth\ForgotPasswordController#showLinkRequestForm')->name('password.reset');
your generated link points to the password/reset and ?451c70284a9d4b41123c4ec3efe83602b6cb955427ac48835200a45980bcf9f3 value is passed as the get parameter.
To trigger your reset the following route
Route::get('password/reset/{token}', 'Auth\ResetPasswordController#showResetForm')->name('password.reset.token');
you should use the following link format
https://myapp.dev/password/reset/451c70284a9d4b41123c4ec3efe83602b6cb955427ac48835200a45980bcf9f3

First of all, in your route
Route::get('password/reset', 'Auth\ForgotPasswordController#showLinkRequestForm')->name('password.reset');
will take precedence over your url. since the route was declared on top and thus will goes into that showLinkRequestForm function first.
Meanwhile in your '/{token}' it will take slashes with the value that you sent thru the get route. Which currently you get.
Route::get('password/reset/{token}', 'Auth\ResetPasswordController#showResetForm')->name('password.reset.token');
Note that, position of route declaration is also affecting . Given example of 2 route with the same url but different name
//1st password/reset
Route::get('password/reset', 'Auth\ForgotPasswordController#showLinkRequestForm')->name('password.reset');
//2nd password/reset
Route::get('password/reset', 'Auth\ForgotPasswordController#showTokenForm')->name('password.reset.form');
In that case route naming will take the latest/last declaration which is 2nd password/reset and the first password/reset will be ignored or made into not available (tested).
So to answer your question which you asking Muhammad Nauman :
"How should I then change my code in order to get given route to work?"
Route::get('password/reset/{token}',
'Auth\ResetPasswordController#showResetForm')->name('password.reset.token');
In blade template you can adjust your routing value looks like this
Reset Form
Inside your new ResetPasswordController.php
public function showResetForm(Request $request)
{
$token = $request->route()->parameter('token');
return view('auth.passwords.reset')->with(
['token' => $token, 'email' => $request->email]
);
}
But if you are kinda like doing dirty way which pass the GET request token email
"?token="somevalue"&email="somevalue" you could do something like this
public function showResetForm()
{
return view('auth.passwords.reset')->with(
['token' => request('token'), 'email' => request('email')]
);
}
Then in the blade you add additional routing parameter of email too
Reset Form

Related

Laravel Redirect url from {id} to {id}/{name}

I am new in laravel framework now I'm working fully developed website using Laravel. I have changed blog url form {id} to {id}/{name} like www.example.com/news/203 to www.example.com/news/203/title. It's working fine. but i need to redirect if old url enter into current url opened from cache or something else.
Route::get('{id}/{name}', 'EventController#show')
->name('events-detail')
->where([
"id" => "[0-9]+"
]);
You can define another route in which you will find the model by id and use its title to redirect the user to the new route:
Route::get('{id}', function ($id) {
$model = Model::findOrFail($id);
return redirect()->route('events-detail', ['id' => $id, 'name' => $model->name]);
});
Note that you have to change Model with the class you use for this route.
Create 2 routes and add below code.
Route::get('{id}/{name}', function () {
//new URL as you want
return redirect()->route({id}/{name});
});
Route::get('{id}', function () {
//as you want for simple URL
});
I'm assuming the name portion is not really used at all, except for SEO/friendlier urls. If this is the case, just make the name parameter optional, and there will be no need for a redirect:
Route::get('{id}/{name?}', 'EventController#show')
->name('events-detail')
->where([
"id" => "[0-9]+"
]);
This route will match /203 and /203/news-title.

How to pass id from (form) of view blade to route (web.php) :Route

I need to pass an id to the route (web.php) from the form. My application has comment section at opporunities/id (id in value) , Whenever non-Auth user submits comment , my app will ask login and redirects to /opportunities but i need /opportunities/id. In the form of comment i have submitted page id. I have setup my route as
Route::post('/opportunities', 'OpportunitiesController#postPost')->name('posts.post'); Now if i can pass that id to as /opportunities/id then after login user will automatically lands on that page. I have manually tested and attached id and it works. Do I need to use "use Illuminate\Http\Request;" to get form data to web.php (route)? to get request post id? All i need is to add id after Route:post('/opportunites/'). Any suggestion and help will be appropriated.
What I did was and figured out is that
action="{{route('opportunities',['returnvalue'=> $post['id']]) }}" I still got error #bipin answer but i passed it with as parameter and solved. Thanks bipin for suggestion though!
One solution could be, pass your post id inside the form
View Blade
{{ Form::hidden('post_id', 'value', array('id' => 'post_id')) }}
Controler
use Illuminate\Http\Request;
public function comment(Request $request)
{
//Validation
$this->validate($request, [
'post_id' => 'required'
]);
//Inside variable
$input = $request->all();
// OR
$request->post_id;
}

Laravel sub-domain routing set global para for route() helper

I have setup sub-domain routing on my app (using Laravel 5.4) with the following web.php route:
Route::domain('{company}.myapp.localhost')->group(function () {
// Locations
Route::resource('/locations' , 'LocationController');
// Services
Route::resource('/services' , 'ServiceController');
});
However as my show and edit endpoints require an ID to be passed, using a normal route('services.show') helper results in an ErrorException stating Missing required parameters for [Route: services.create] [URI: services/create].
I appreciate this is necessary, but as the company is associated to the user on login (and is in the sub-domain) I don't want to be passing this for every view. I want to set this at a global level.
To avoid repeated queries, I thought about storing this in the session as so (in the :
protected function authenticated(Request $request, $user)
{
$current_company = $user->companies->first();
$company = [
'id' => $current_company->id,
'name' => $current_company->name,
'display_name' => $current_company->display_name
];
$request->session()->put('company', $company);
}
Which is fine, but I wonder if I can pass this to the route as a middleware or something. What's be best solution here?
Recommendation: remove the slash before the resource name.
The resource method will produce the following URIs:
/services/{service}
So, you should define your routes like this:
Route::domain('{company}.myapp.localhost')->group(function () {
// Locations
Route::resource('locations' , 'LocationController');
// Services
Route::resource('services' , 'ServiceController', ['only' => ['index', 'store']]);
Route::get('services');
});
I ran into this exact issue today, I poked around in the source and found a defaults method on the url generator that allows you to set global default route parameters like so:
app('url')->defaults(['yourGlobalRouteParameter' => $value]);
This will merge in whatever value(s) you specify into the global default parameters for the route url generator to use.

Accessing Route URL Parameter in Middleware in Laravel 5.3

I am having a hard time accessing the Route URL Parameter in Middleware after updating from Laravel 5.1 to Laravel 5.3.
Here is my route file:
Route::group(['middleware' => ['app.access']], function()
{
Route::resource('apps/{apps}/houses', 'HouseController',
['except' => ['index', 'create', 'edit']]);
Route::get('apps/{apps}/houses/colour/{colour}', 'HouseController#colourCheck');
...
}
Kernel.php has RouteMiddleware updated like this:
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
// Added ones....
'jwt.auth' => \Tymon\JWTAuth\Middleware\GetUserFromToken::class,
'jwt.refresh' => \Tymon\JWTAuth\Middleware\RefreshToken::class,
// Custom Middleware
'app.access' => \App\Http\Middleware\AppAccess::class,
];
In Laravel 5.1 and I was able to access route parameter from middleware like this and I had no trouble:
public function handle($request, Closure $next)
{
$appId = $request->route('apps');
...
}
But, since upgrading to Laravel 5.3, the above code started returned $appId as null. I also tried accessing route parameter like $appId = $request->apps and this was not working as well.
So I then changed the Middleware to get the url parameter like this:
public function handle($request, Closure $next)
{
$appId = $request->route()->parameters('apps');
...
}
Since changing to the above, the middleware seems to be working for the first route. But then, I am having problem when going to the second route that has 2 parameters. For some reason, the above code fails and when returning $request->route()->parameters('apps') from middleware, I am getting an array like this:
Array
(
[apps] => 1
[colour] => green
)
Why is that? Why is it not returning just the $appId which is 1? Am I missing something or is it a bug in Laravel 5.3? I want the Middleware to access only the appId parameter from the url and nothing else from the route. Can someone help me here please?
Update 1:
I tried changing the Middleware to get parameter like this:
$parameters = $request->route()->parameters();
$appId = $parameters['apps'];
In the above, I am getting the error:
Undefined index: apps
But when I print_r($parameters);, the output is like this:
Array
(
[apps] => 1
[day] => tuesday
)
[]
Solution:
In the end, I found out the reason for this odd behaviour was due the parameter name in the url.
The following resources routes were generating route url parameter as app instead of apps. I dont know why though:
Route::resource('apps/{apps}/houses', 'HouseController',
['except' => ['index', 'create', 'edit']]);
Whereas the following routes were generating route url parameter as apps:
Route::get('apps/{apps}/houses/colour/{colour}', 'HouseController#colourCheck');
Due to this odd behaviour, some routes were returning null for the parameter name apps and some where showing the parameter. Once I renamed all route parameters to {app} in the routes/api.php and Middleware, the Middleware started working the way it should.
I don't know why the resource routes were creating the parameter as app, but the above fixed the error for me, atleast for now.
There are two ways for accessing parameters in a middleware:
Method 1
$request->route('parameter_name');
Here parameter_name refers to what we called the parameter in the route.
Method 2
$request->route()->parameters();
This method will return an array of all the parameters.
Resource Parameters Are Singular By Default
If you would like to maintain the previous behavior instead of automatically singularizing resource route parameters, you may make the following call to the singularResourceParameters method in your AppServiceProvider:
use Illuminate\Support\Facades\Route;
Route::singularResourceParameters(false);
For me, this was the solution for Laravel 6.
In the routes file add ->middleware() like this:
Route::resource('orders', 'OrdersController')->middleware('roles:Admin,System');
Now to retrieve the parameters in the middleware class:
public function handle($request, Closure $next, ...$roles)
{
// now $roles contains: ['Admin, 'System']
}

Laravel Redirect to route with Parameters

This is my code:
return redirect()->route('edit.brand',$id)->with(array( 'brand' => $brand, 'errorName' => $errorName, 'errorCode' => $errorCode));
The result is that, in the FORM of route edit.brand.
It's filled by data with $id, (do the route first and ignore all parameters in 'with' )
How can I show $errorName if they exist
When You are redirecting to route, your parameters goes to flash session. So in edit.brand route You can access it with session helper like so:
session('errorName')
This is for flash data not request parameters That you are using .
Use this one
return Redirect::route('user', array('nick' => $username));

Resources