Laravel Route URL in Notification Email Defaults to HTTP - https

I am creating email notifications in Laravel 9 that contain a button with a URL. I am using the name attribute from the route to pass along the proper route from the web.php file.
When the user gets the email notification, the URL defaults to "http://" rather than "https://".
I have the proper HTTPS redirect on the server, but I'd like the original URL to default to HTTPS. Any idea how to do this?
Example route from web.php:
Route::get('/home', [HomeController::class, 'home'])->name('home');
Example notification button line in the HomeController:
$notify_data = [
... content stuff here ...
'url' => route('home' ),
];
$user->notify( new Step3($notify_data) );
And finally the button in the Step3 Notification:
public function toMail($notifiable)
{
return (new MailMessage)
... content stuff here ...
->action('View Dashboard', $this->notify_data['url']);
}
Expectation:
URL in email: https://www.example-domain.com/home
Current result:
URL in email: http://www.example-domain.com/home

Use secure_url method
'url' => secure_url(route( 'home', [], false)),
The secure_url function generates a fully qualified HTTPS URL to the given path. Additional URL segments may be passed in the function's second argument:

Related

How to send to laravel request with api prefix?

location #laravelapi {
rewrite /api/(.*)?$ /api/index.php?$is_args$args last;
}
When we try access to api/routeexample, laravel gets only routeexample part, and throws 404 error. How we can send full url including 'api' part?
I m adding an example of how we define route for API request:
In routes/api.php
Route::group(['prefix' => 'v1'], function () {
Route::post('api_request', [App\Http\Controllers\YourController::class, 'targeted_function_name'])->name('api_request');
});
So I'm just added
include "api.php";
into my routes/web.php as hotfix, but i will search for better solution

How to redirect properly after logging in in an SPA

I have a situation. I am trying to create an application that will have only one route file, api.php for both the web app (spa) and mobile app.The problem is now that the entire application is stateless (as it should be), I can't even login. Because, routes in api.php expect a token in the request header, which I don't know how to provide.I am using vue in the front-end I have this simple strategy:<button #click="login">Login</button>and the login method looks like this:
login(){
axios.post('login',this.credentials)
.then( window.location = "http://localhost:3000/app" );
}
And my route definition:
Route::group(['middleware' => ['role:admin']], function () {
Route::get('app', function () {
return view('index');
});
});
But it redirects me back to the login page. I wish I could do something like window.header = Bearer myLongToken. I am using JWT, if that helps.
Update:
It looks like there is something else going on. If I remove the role:admin middleware, then I get redirected to desired route, but if I add the middleware, I get redirected back to the login route even if the credentials are valid.
// Route::group(['middleware' => ['role:admin']], function () {
Route::get('app', function () {
return view('index');
});
// });

laravel_token is valid for first request but not subsequent requests

I have installed Laravel Passport and configured it according to the documentation. When calling axios.get from my VueJS file, the first call works as expected. the laravel_session Request Cookie is injected into the request, and the authentication passes, returning the resource.
My problem arises when I try to call the axios.get method again. My use case here is a search function. I'm making a call to /api/banking/accounts/search/{search-term} whenever the user types into a text field, using the code below:
remoteMethod(query) {
if (query !== '') {
this.loading = true;
axios.get(
`/api/banking/accounts/search/${escape(query)}`
).then(res => {
this.destinationAccountDirectory = res.data;
this.loading = false;
});
} else {
this.destinationAccountDirectory = [];
}
},
This code works fine without any auth:api middleware on the route, and for the first time with auth:api middleware. As can be seen from the screenshots below, the laravel_token value changes and is rejected on subsequent calls to the API.
**I've tried to removed the \Laravel\Passport\Http\Middleware\CreateFreshApiToken that was added to the web middleware group during passport installation, which seemed to have temporarily solved the issue, until I receive a 419 on a request shortly after. What could be causing the new laravel_tokens to be rejected? **
I solved this by removing the web middleware from my API route. Why it was there in the first place, I have no idea.
I changed my api.php from
Route::group([
'middleware' => [
'web',
'auth:api']], function() {
Route::post('/banking/transactions', 'TransactionController#store');
Route::get('/banking/accounts', 'BankAccountDirectoryController#index');
Route::get('/accounts/{account}', 'BankAccountDirectoryController#show');
Route::get('/banking/accounts/search/{term?}', 'BankAccountDirectoryController#search');
});
to
Route::group([
'middleware' => [
'auth:api']], function() {
Route::post('/banking/transactions', 'TransactionController#store');
Route::get('/banking/accounts', 'BankAccountDirectoryController#index');
Route::get('/accounts/{account}', 'BankAccountDirectoryController#show');
Route::get('/banking/accounts/search/{term?}', 'BankAccountDirectoryController#search');
});
Should the API routes be under the web group to benefit from the middleware, or is it purely for UI? Am I safe to do this?

Laravel vs. Ajax: incorrect routing

I'm trying to populate "position" dropdown based on "department". The Ajax call is triggered on change event of the "department" dropdown.
The problem is that the Ajax call can't reach the correct route:
with url: 'ajax/get-position' - the url is: localhost/public/join/ajax/get-position?dept_id=5
with url: '/ajax/get-position' - the url is: localhost/ajax/get-position?dept_id=5
Both of the URLs are wrong and I have no idea why. Especially this /join/ in the first point is a mystery to me. The correct URL should be localhost/public/ajax/get-position?dept_id=5. I believe there's some kind of a conflict in the routing, however I'm not sure where.
The Ajax call is made on localhost/public/join/editor page.
JS:
...
...
$.ajax({
url: 'ajax/get-position',
data: {
dept_id: value
},
type: 'GET',
dataType : 'json',
success: function(json) {
//
},
error: function(xhr, status, errorThrown) {
//
}
});
...
...
Routes:
Route::get('join/editor',
array(
'uses' => 'DefaultController#showEditorRegistration',
'as' => 'editorRegistration'
)
);
Route::post('join/editor',
array(
'uses' => 'DefaultController#createEditor',
'as' => 'createEditor'
)
);
// ROUTE FOR AJAX CALL
Route::get('ajax/get-position',
array(
'uses' => 'DefaultController#getPositionsByDepartment',
)
);
Any ideas?
EDIT:
The JavaScript is in an external file. If I put the JS directly in blade.php view and use URL::route('routename') as Ajax url value - all works fine. However, simply using url: ajax/get-position - does not. Crazy world.
I'm not completely sure, but based on our conversation about the details of your project I think the issue has to do with the location of your document root. the public directory should never show up in any of your laravel project's urls.
I created a demo project to demonstrate a simple interaction with Laravel and Ajax. It's a vanilla laravel project with slight alterations to the hello view.
Checkout the project, navigate into the public folder, and use the following command to spin up an ad-hoc phpserver:
php -S localhost:8002
You can then go to the url http://localhost:8002 to get to the homepage.
If you inspect the link on the home page and look at the url that is generated with the URL facade for the route tester. The URL doesn't include the public directory:
http://localhost:8003/tester
You can also look at the ajax setup and see that you can use the tester route as well.
$('#getbutton').click( function (){
$.ajax({
url: 'tester'
}).complete(function (a){
alert(a.responseText);
}).error(function (a){
console.log(a);
});
});
Using either the link or the ajax call on button click will hit the tester route in the routes file:
Route::get('tester',[ 'as' => 'tester', 'uses' => function (){
return 'worked';
}]);
The link can hit the route via the route name tester assigned in the routes file, and the ajax request can hit the route from the query string.
The routes in your project look ok and using ajax/get-position as your url in the ajax call shouldn't be an issue.
Give this project a try. Even if the issue isn't a webroot one, hopefully it will help you figure out where your issue is coming from.

Laravel 3 HTTP and HTTPS routes

I have the following code:
Route::get('/', function()
{
return 'non secure page';
});
Route::get('/', array('https' => true, function()
{
return 'secure page';
}));
What I expected to happen is that these two routes would be treated differently. The first is for http://example.com requests and the second for https://example.com. Respectively, these pages should show the text 'non secure page' and 'secure page'. What actually happens is that both show the text 'secure page'. This must mean that both routes are treated the same i.e. it doesn't matter if the request was over https or http - the same route is triggered.
I know I can resolve my issue by using if (Request::secure()){ //routes }; but that then leads me to the question what use are the HTTPS secure routes in laravel? What do they achieve and when should they be used?
I've looked at the docs, but it's not clear to me what is supposed to happen.
The documentation says:
When defining routes, you may use the "https" attribute to indicate that the HTTPS protocol should be used when generating a URL or Redirect to that route.
"https" and ::secure() are only used when generating URLs to routes, they're not used to provide https-only routes. You could write a filter to protect against non-HTTPS routes (example below). Or if you want to prevent any non-HTTPS access to your entire domain then you should reconfigure your server, rather than do this in PHP.
Route::filter('https', function() {
if (!Request::secure()) return Response::error(404);
});
Alternative filter response:
Route::filter('https', function() {
if (!Request::secure()) return Redirect::to_secure(URI::current());
});
References:
http://laravel.com/docs/routing#https-routes
http://laravel.com/docs/routing#filters
The problem is not related to HTTPS.
The documentation says,
Note: Routes are evaluated in the order that they are registered, so register any "catch-all" routes at the bottom of your routes.php file.
It means that your
Route::get('/', array('https' => true, function()
{
return 'secure page';
}));
is over-writing
Route::get('/', function()
{
return 'non secure page';
});
I was actually lead here by Spark from laravel.io and I thought I would clarify the doubt anyhow.
Regards

Resources