Laravel+Vue密码重置跳转异常求助:链接导向Laravel而非Vue
密码重置链接跳转异常问题
问题详情
我使用Laravel后端搭配Vue前端开发网站的密码找回功能,采用Mailhog作为邮件测试工具。目前已成功发送密码重置邮件至Mailhog并能接收,邮件内的重置按钮本应跳转至Vue项目的reset.vue页面完成密码重置,但实际点击后却导向Laravel项目页面。尝试将.env配置文件中的APP_URL修改为Vue运行端口时出现错误,设置为Laravel运行端口则跳转至Laravel项目,特此寻求解决方法。
相关代码
Vue找回密码组件
<template> <form > <div> <label for="email">Email:</label> <input type="email" name="email" v-model="email" required> </div> <v-btn @click="submitForm">Send Password Reset Link</v-btn> </form> </template> <script> import axios from 'axios'; export default { data() { return { email: '' }; }, methods: { submitForm() { axios.post('http://127.0.0.1:8000/api/forgotpassword', { email: this.email }) .then(response => { console.log(response.data); // Show success message to the user }) .catch(error => { console.log(error.response.data); // Show error message to the user }); } } }; </script>
Vue重置密码组件
<template> <form> <div> <label for="password">New Password:</label> <input type="password" name="password" v-model="password" required> </div> <div> <label for="password_confirmation">Confirm Password:</label> <input type="password" name="password_confirmation" v-model="password_confirmation" required> </div> <v-btn @click="submitForm">Reset Password</v-btn> </form> </template> <script> import axios from 'axios'; export default { data() { return { password: '', password_confirmation: '', email : '' }; }, methods: { submitForm() { let token = this.$route.params.token; axios.post(`http://127.0.0.1:8000/api/resetpassword/${token}`, { email: this.email, password: this.password, password_confirmation: this.password_confirmation, token: token, }) .then(response => { console.log(response.data); // Show success message to the user }) .catch(error => { console.log(error.response.data); // Show error message to the user }); } } }; </script>
Laravel控制器代码
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\User; use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Password; use Illuminate\Support\Facades\Hash; class forgotPassController extends Controller { public function sendResetLinkEmail(Request $request) { $request->validate(['email' => 'required|email']); $response = $this->broker()->sendResetLink($request->only('email')); if ($response == Password::RESET_LINK_SENT) { return response()->json(['message' => 'Reset link sent to your email.']); } return response()->json(['error' => 'Failed to send reset link.'], 400); } protected function broker() { return Password::broker(); } public function reset(Request $request) { $request->validate([ 'token' => 'required', 'email' => 'required|email', 'password' => 'required|confirmed|min:8', ]); $response = $this->broker()->reset( $request->only('email', 'password', 'password_confirmation', 'token'), function ($user, $password) { $user->password = Hash::make($password); $user->save(); } ); if ($response == Password::PASSWORD_RESET) { return response()->json(['message' => 'Password has been reset.']); } return response()->json(['error' => 'Failed to reset password.'], 400); } }
.env配置
APP_NAME=Laravel APP_ENV=local APP_KEY=base64:Z3YlschFLAephSU75DAFaJsMtEEjcgMXiqw5b9OPL3o= APP_DEBUG=true # APP_URL=http://localhost APP_URL=http://localhost:8081 LOG_CHANNEL=stack LOG_DEPRECATIONS_CHANNEL=null LOG_LEVEL=debug DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=backfinalproject DB_USERNAME=root DB_PASSWORD= BROADCAST_DRIVER=log CACHE_DRIVER=file FILESYSTEM_DISK=local QUEUE_CONNECTION=sync SESSION_DRIVER=file SESSION_LIFETIME=120 MEMCACHED_HOST=127.0.0.1 REDIS_HOST=127.0.0.1 REDIS_PASSWORD=null REDIS_PORT=6379 MAIL_MAILER=smtp MAIL_HOST=localhost MAIL_PORT=1025 MAIL_USERNAME= MAIL_PASSWORD= MAIL_ENCRYPTION= MAIL_FROM_ADDRESS="hello@example.com" MAIL_FROM_NAME="${APP_NAME}" AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= AWS_DEFAULT_REGION=us-east-1 AWS_BUCKET= AWS_USE_PATH_STYLE_ENDPOINT=false PUSHER_APP_ID= PUSHER_APP_KEY= PUSHER_APP_SECRET= PUSHER_HOST= PUSHER_PORT=443 PUSHER_SCHEME=https PUSHER_APP_CLUSTER=mt1 VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}" VITE_PUSHER_HOST="${PUSHER_HOST}" VITE_PUSHER_PORT="${PUSHER_PORT}" VITE_PUSHER_SCHEME="${PUSHER_SCHEME}" VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
解决办法
1. 自定义密码重置通知,指定前端跳转链接
Laravel默认依赖APP_URL生成重置链接,直接修改APP_URL会破坏Laravel自身功能。正确做法是自定义密码重置邮件的跳转地址:
生成自定义通知类
在终端执行:
php artisan make:notification CustomPasswordResetNotification
修改通知类代码
打开app/Notifications/CustomPasswordResetNotification.php,替换为以下内容:
<?php namespace App\Notifications; use Illuminate\Bus\Queueable; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Notification; class CustomPasswordResetNotification extends Notification { use Queueable; public $token; public function __construct($token) { $this->token = $token; } public function via($notifiable) { return ['mail']; } public function toMail($notifiable) { // 替换为你的Vue前端重置页面地址,携带token和email参数 $resetUrl = env('FRONTEND_URL') . '/reset?token=' . $this->token . '&email=' . $notifiable->email; return (new MailMessage) ->line('你收到这封邮件是因为我们收到了你的密码重置请求。') ->action('重置密码', $resetUrl) ->line('若未发起该请求,可忽略此邮件。'); } }
在User模型中替换默认通知逻辑
打开app/Models/User.php,添加以下方法:
use App\Notifications\CustomPasswordResetNotification; // ... public function sendPasswordResetNotification($token) { $this->notify(new CustomPasswordResetNotification($token)); }
2. 配置前端地址环境变量
在.env文件末尾添加前端地址:
FRONTEND_URL=http://localhost:8081
然后清除Laravel配置缓存并重启服务:
php artisan config:clear
3. 完善Vue重置页面的参数接收
修改Vue的reset.vue组件,在页面加载时获取URL中的token和email:
<script> import axios from 'axios'; export default { data() { return { password: '', password_confirmation: '', email: '', token: '' }; }, created() { // 从URL查询参数中获取token和email const queryParams = new URLSearchParams(this.$route.query); this.token = queryParams.get('token'); this.email = queryParams.get('email'); }, methods: { submitForm() { axios.post('http://127.0.0.1:8000/api/resetpassword', { email: this.email, password: this.password, password_confirmation: this.password_confirmation, token: this.token }) .then(response => { console.log(response.data); // 显示成功提示,比如跳转到登录页 }) .catch(error => { console.log(error.response.data); // 显示错误提示 }); } } }; </script>
4. 调整Laravel重置密码路由
打开routes/api.php,确保重置路由接收POST请求且无需在URL中携带token:
use App\Http\Controllers\forgotPassController; // 找回密码请求 Route::post('/forgotpassword', [forgotPassController::class, 'sendResetLinkEmail']); // 重置密码请求 Route::post('/resetpassword', [forgotPassController::class, 'reset']);
5. 恢复Laravel的APP_URL配置
将.env中的APP_URL改回Laravel服务地址:
APP_URL=http://localhost:8000
这样配置后,密码重置邮件中的链接会正确指向Vue的reset页面,同时Laravel自身功能不受影响。
内容的提问来源于stack exchange,提问作者aliana
相关产品推荐
相关产品推荐

