学习 L01 Laravel 教程 - Web 开发实战入门 ,学到9.3章的时候,报错
local.ERROR: Route [password.reset] not defined. {"exception":"[object] (Symfony\\Component\\Routing\\Exception\\RouteNotFoundException(code: 0): Route [password.reset] not defined. at /home/vagrant/code/weibo/vendor/laravel/framework/src/Illuminate/Routing/UrlGenerator.php:420)
[stacktrace]
定位了一下错误,最后发现错误在 Illuminate\Auth\Notifications\ResetPassword
/**
* Build the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
if (static::$toMailCallback) {
return call_user_func(static::$toMailCallback, $notifiable, $this->token);
}
if (static::$createUrlCallback) {
$url = call_user_func(static::$createUrlCallback, $notifiable, $this->token);
} else {
$url = url(route('password.reset', [
'token' => $this->token,
'email' => $notifiable->getEmailForPasswordReset(),
], false));
}
return (new MailMessage)
->subject(Lang::get('Reset Password Notification'))
->line(Lang::get('You are receiving this email because we received a password reset request for your account.'))
->action(Lang::get('Reset Password'), $url)
->line(Lang::get('This password reset link will expire in :count minutes.', ['count' => config('auth.passwords.'.config('auth.defaults.passwords').'.expire')]))
->line(Lang::get('If you did not request a password reset, no further action is required.'));
}
因为其默认值为 password.reset ,而我并没有定义此路由的别名,定义的是 passwords.reset ,因为我习惯使用复数,所以这里改了。导致报错。
// 教程代码
Route::get('password/reset/{token}', 'Auth\ResetPasswordController@showResetForm')->name('password.reset');
// 自己的代码
Route::get('passwords/reset/{token}','Auth\ResetPasswordController@showResetForm')->name('passwords.reset');
我并不想使用单数,所以我选择了不修改路由,解决此问题。解决方法有两种:
第一种方法 :简单粗暴,在 App\Providers\AppServiceProvider 中的 boot 方法添加如下代码
ResetPassword::createUrlUsing(function ($notifiable, $token) {
//此处为你的URL
return "http://www.my-spa.co/password/reset/{$token}";
});
第二种方法 在用户模型(一般为 App\Models\User 模型,没移动的话为 App\User)中重写 sendPasswordResetNotification 方法
第一步:在 User 模型中添加一下代码
// App\Notifications\Auth\MailResetPasswordToken 在下面生成
use App\Notifications\Auth\MailResetPasswordToken;
/**
* Send the password reset notification.
*
* @param string $token
* @return void
*/
public function sendPasswordResetNotification($token)
{
$this->notify(new AdminMailResetPasswordToken($token));
}
第二步:添加 AdminMailResetPasswordToken 类 ,在 app 目录下创建 Notifications 目录 ,在Notifications里面创建 Auth 目录,在 app/Notifications/Auth 目录创建 MailResetPasswordToken.php
<?php
namespace App\Notifications\Auth;
use Illuminate\Auth\Notifications\ResetPassword;
class MailResetPasswordToken extends ResetPassword
{
public static $createUrlCallback = [self::class, 'createActionUrl'];
public static function createActionUrl($notifiable, $token)
{
// 如果你的不是passwords.reset,请把 passwords.reset 改成你的路由名称
return url(route('passwords.reset', [
'token' => $token,
'email' => $notifiable->getEmailForPasswordReset(),
], false));
}
}