'Laravel - Alternative root domain on verification email link
I have a Laravel application which can be accessed from multiple clients all of which have their own domain (eg myclient.com). In addition, there is a core client (for the sake of this example using the domain coreclient.org).
Users associated to the core client are able to sign up users for any of the other clients.
Admin users for any other client are able to sign up users only for their client.
This uses the base code from Fortify.
It's all fine until it comes to the account verification email when a new user is created by the core client for a different client. The link in the verification email uses the core client domain rather than client the new user belongs to.
eg http://coreclient.org/email/verify/1/dd8...8ad?expires=1639608547&signature=718...1ee
It needs to be http://myclient.com/email/verify/1/dd8...8ad?expires=1639608547&signature=718...1ee
To fix this, I replaced the domain in the url string after it is generated but this causes an invalid signature as I'm assuming this is generated based on the domain of the person creating the new user.
Here's what I have so far in the boot function of my AuthServiceProvider file... any ideas?
VerifyEmail::createUrlUsing(function ($notifiable) {
$verifyUrl = URL::temporarySignedRoute(
'verification.verify',
Carbon::now()->addMinutes(Config::get('auth.verification.expire', 60)),
[
'id' => $notifiable->getKey(),
'hash' => sha1($notifiable->getEmailForVerification()),
]
);
// This amends the domain in the URL if core client user creating for another client - creates mismatch with signature though
if(auth()->user()->client->is_core && auth()->user()->client_id != $notifiable->client_id) {
$verifyUrl = Str::replace(auth()->user()->client->domains->first()->domain, $notifiable->client->domains->first()->domain, $verifyUrl);
}
return $verifyUrl;
});
Solution 1:[1]
The signature depends on your APP_KEY
.
To publish it to other application should not discussed. It is a no go.
You can customize with key which it should resolved with.
Paste this code in here:
App\Providers\AppServiceProvider.php
public function register()
{
$this->app->make('url')->setKeyResolver(function () {
return $this->app->make('config')->get('app.shared-signed-key');
});
}
This code needs to be on the coreclient
and on the myclient
so they can both generate and resolve it.
You can get a deep view with following methods:
\Illuminate\Routing\UrlGenerator::signedRoute
\Illuminate\Routing\UrlGenerator::setKeyResolver
\Illuminate\Routing\RoutingServiceProvider::registerUrlGenerator
Solution 2:[2]
I had a similar problem: I needed to send the link with a subdomain; Check my own answer here:
https://stackoverflow.com/a/71973086/1825418
you'll have to adapt the code because i use "tenan_route" which is a function from the tenancy_laravel, which automatically add the subdomain route, in your case you just nee to change that function to some other with the full domain domain you want to use in both positions where i use "tenant_route" (one for the link itsel, the other to be used by laravel to generate the correct signature)
It works like a charm!
Good Luck
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Dharman |
Solution 2 | Nuno |