Laravel 登录后重定向回原始目的地

222

这似乎是一个相当基础的流程,而且 Laravel 有许多好的解决方案来处理基本的事情,我觉得我可能遗漏了什么。

用户点击需要身份验证的链接。 Laravel 的 auth 过滤器启动并将用户路由到登录页面。 用户登录后,再次访问之前被“auth”过滤器拦截的原始页面。

有没有一种很好的方法可以知道他们最初想要进入哪个页面?由于 Laravel 拦截请求,我不知道它是否在某处记录以便用户登录后轻松路由。

如果没有,我很想听听你们中的一些人如何手动实现这一点。

26个回答

3

使用Redirect;指令

然后使用以下命令:

return Redirect::back();

1
在 Laravel 5.8 中,在 App\Http\Controllers\Auth\LoginController 中添加以下方法。
public function showLoginForm()
{
    if(!session()->has('url.intended'))
        {
            session(['url.intended' => url()->previous()]);
        }
    return view('auth.login');
}

在App\Http\Middleware\RedirectIfAuthenticated中,用以下内容替换" return redirect('/home'); "

 if (Auth::guard($guard)->check()) 
    {
        return redirect()->intended();
    }

0
这是我对5.1的解决方案。我需要有人点击帖子上的“赞”按钮,被重定向到登录页面,然后返回原始页面。如果他们已经登录,则使用JavaScript拦截“赞”按钮的href,并将其转换为AJAX请求。
该按钮类似于喜欢这篇文章!。 / like / 931由LikeController处理,需要auth中间件。
在Authenticate中间件(handle()函数)中,在开头添加以下内容:
    if(!str_contains($request->session()->previousUrl(), "/auth/login")) {
        $request->session()->put('redirectURL', $request->session()->previousUrl());
        $request->session()->save();
    }

/auth/login更改为您用于登录的任何URL。此代码将原始页面的URL保存在会话中,除非URL是登录URL。这是必需的,因为它似乎会调用此中间件两次。我不确定为什么或是否正确。但是,如果您不检查该条件,则它将等于正确的原始页面,然后以某种方式被更改为/auth/login。可能有更优雅的方法来解决这个问题。

然后,在LikeController或处理原始页面上按钮推送的任何控制器中:

//some code here that adds a like to the database
//...
return redirect($request->session()->get('redirectURL'));

这种方法非常简单,不需要覆盖任何现有的函数,并且效果很好。Laravel 可能有更简单的方法来实现这一点,但我不确定是什么。在我的情况下,使用 intended() 函数无法工作,因为 LikeController 还需要知道先前的 URL 是什么才能重定向回去。本质上是两个级别的后退重定向。


0
如果在路由级别处理过滤器,那么只需要将一个auth中间件附加到您的原始链接上,就可以非常简单地进行操作。当用户成功通过中间件检查(表示他们已登录)时,他们会自动重定向到所需的目的地。例如,您可以这样做,而不是在控制器中检查身份验证。
Route::get('/appointments',[AppointmentsController::class,'appointments'])->middleware(['auth'])->name('appointments');

0

现在是2022年9月,我想分享一下我为OP的问题所做的事情。请对我宽容,我还是个新手。
我的问题:在我实现了MustVerifyEmail之后,上面的解决方案不起作用了。我使用的是Laravel 6.x。
所以,在整整一个晚上的头痛和无数杯咖啡的帮助下,终于现在它可以工作了。这不是新的解决方案,因为它是从之前的答案修改而来的。
第一步:
意识到:具有名称'url.intended'的会话已经被vendor\laravel\framework\src\Illuminate\Routing\Redirector.php占用了。
所以我选择使用不同的会话名称:'url_intended'
第二步:
添加这行代码:

session(['url_intended' => url()->previous()]);

在app\Http\Middleware\Authenticate.php中有以下类似的内容:
<?php
namespace App\Http\Middleware;
use Illuminate\Auth\Middleware\Authenticate as Middleware;
class Authenticate extends Middleware
{
    /**
     * Get the path the user should be redirected to when they are not authenticated.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return string
     */
    protected function redirectTo($request)
    {
        session(['url_intended' => url()->previous()]);
        if (! $request->expectsJson()) {
            return route('login');
        }
    }
}

现在,关键的解决方案来了。我没有成功地修改app\Http\Controllers\Auth\LoginControllerapp\Http\Middleware\RedirectIfAuthenticated.php,我修改了vendor\laravel\framework\src\Illuminate\Auth\Middleware\EnsureEmailIsVerified.php,并添加了以下内容(复制并稍作修改上面的先前答案)。
if (session()->has('url_intended')) {
    $redirectURL = session()->get('url_intended');
    session()->forget('url_intended');
    return redirect($redirectURL);
}

以下是完整的代码:
<?php

namespace Illuminate\Auth\Middleware;

use Closure;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Support\Facades\Redirect;

class EnsureEmailIsVerified
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string|null  $redirectToRoute
     * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
     */
    public function handle($request, Closure $next, $redirectToRoute = null)
    {
        if (! $request->user() ||
            ($request->user() instanceof MustVerifyEmail &&
            ! $request->user()->hasVerifiedEmail())) {

            return $request->expectsJson()
                    ? abort(403, 'Your email address is not verified.')
                    : Redirect::route($redirectToRoute ?: 'verification.notice');
        }

        if (session()->has('url_intended')) {
            $redirectURL = session()->get('url_intended');
            session()->forget('url_intended');
            return redirect($redirectURL);
        }

        return $next($request);
    }
}

它的工作非常出色。

更新: 只需基于现有的EnsureEmailIsVerified中间件创建新的中间件,并将其附加到Kernel.php中:

protected $routeMiddleware = [
    //other middlewares here..
    'verified' => \App\Http\Middleware\EnsureEmailIsVerified::class,
];

0

针对Laravel 5.5和可能是5.4版本

App\Http\Middleware\RedirectIfAuthenticated中,在handle函数中将redirect('/home')更改为redirect()->intended('/home')

public function handle($request, Closure $next, $guard = null)
{
    if (Auth::guard($guard)->check()) {
        return redirect()->intended('/home');
    }

    return $next($request);
}

App\Http\Controllers\Auth\LoginController 中创建以下 showLoginForm() 函数:
public function showLoginForm()
{
    if(!session()->has('url.intended'))
    {
        session(['url.intended' => url()->previous()]);
    }
    return view('auth.login');
}

这样就可以重定向到另一个页面,否则会重定向到主页。


0

Laravel现在支持这个功能,开箱即用! (我相信自5.5或更早以来就开始支持了)。

按照下面所示,在Controller中添加一个__construct()方法:

public function __construct()
{
    $this->middleware('auth');
}

登录后,您的用户将被重定向到他们最初想要访问的页面。

您还可以根据应用程序逻辑添加Laravel的电子邮件验证功能:

public function __construct()
{
    $this->middleware(['auth', 'verified']);
}

文档中包含一个非常简短的示例:

还可以使用 exceptonly 选项来选择中间件应用于哪个控制器的方法。

使用 except 的示例:

public function __construct()
{
    $this->middleware('auth', ['except' => ['index', 'show']]);
}

使用only的示例:

public function __construct()
{
    $this->middleware('auth', ['only' => ['index', 'show']]);
}

有关 exceptonly 中间件选项的更多信息:


0
如果您正在使用axios或其他AJAX JavaScript库,您可能希望检索URL并传递给前端。
您可以使用以下代码实现:
   $default = '/';

   $location = $request->session()->pull('url.intended', $default);

    return ['status' => 200, 'location' => $location];

这将返回一个JSON格式的字符串。

-1

针对 Laravel 5.2(之前的版本我没有使用过)

将代码粘贴到文件 app\Http\Controllers\Auth\AurhController.php 中

   /**
 * Overrides method in class 'AuthenticatesUsers'
 *
 * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
 */
public function showLoginForm()
{
    $view = property_exists($this, 'loginView')
        ? $this->loginView : 'auth.authenticate';
    if (view()->exists($view)) {
        return view($view);
    }
    /**
     * seve the previous page in the session
     */
    $previous_url = Session::get('_previous.url');
    $ref = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
    $ref = rtrim($ref, '/');
    if ($previous_url != url('login')) {
        Session::put('referrer', $ref);
        if ($previous_url == $ref) {
            Session::put('url.intended', $ref);
        }
    }
    /**
     * seve the previous page in the session
     * end
     */
    return view('auth.login');
}
/**
 * Overrides method in class 'AuthenticatesUsers'
 *
 * @param Request $request
 * @param $throttles
 *
 * @return \Illuminate\Http\RedirectResponse
 */
protected function handleUserWasAuthenticated(Request $request, $throttles)
{
    if ($throttles) {
        $this->clearLoginAttempts($request);
    }
    if (method_exists($this, 'authenticated')) {
        return $this->authenticated($request, Auth::guard($this->getGuard())->user());
    }
    /*return to the previous page*/
    return redirect()->intended(Session::pull('referrer'));
    /*return redirect()->intended($this->redirectPath()); /*Larevel default*/
}

导入命名空间:use Session;

如果您没有对文件app\Http\Controllers\Auth\AurhController.php进行任何更改,您可以直接用GitHub上的文件替换它。


-1

对于 Laravel 5.7,您需要进行以下更改:

Middleware>RedirectIfAuthenticated.php

将此更改为:

public function handle($request, Closure $next, $guard = null)
    {
        if (Auth::guard($guard)->check()) {
            return redirect('/admin');
        }

        return $next($request);
    }

转换为这个:

public function handle($request, Closure $next, $guard = null)
    {
        if (Auth::guard($guard)->check()) {
            return redirect('/yourpath');
        }

        return $next($request);
    }

返回重定向('/你的路径');

mypath是什么?(用户密码以便返回此) - Mostafa Norzade

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接