ChatGPT解决这个技术问题 Extra ChatGPT

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

这似乎是一个非常基本的流程,Laravel 为基本的事情提供了很多很好的解决方案,我觉得我错过了一些东西。

用户单击需要身份验证的链接。 Laravel 的 auth 过滤器启动并将它们路由到登录页面。用户登录,然后转到他们在“身份验证”过滤器启动之前尝试访问的原始页面。

有没有一种好方法可以知道他们最初试图访问哪个页面?由于 Laravel 是拦截请求的那个,我不知道它是否会在用户登录后跟踪某个地方以便于路由。

如果没有,我很想知道你们中的一些人是如何手动实现的。


v
vFragosop

对于 Laravel 5.3 及更高版本

检查下面的Scott's answer

对于 Laravel 5 到 5.2

简单的说,

在 auth 中间件上:

// redirect the user to "/login"
// and stores the url being accessed on session
if (Auth::guest()) {
    return redirect()->guest('login');
}
return $next($request);

登录操作:

// redirect the user back to the intended page
// or defaultpage if there isn't one
if (Auth::attempt(['email' => $email, 'password' => $password])) {
    return redirect()->intended('defaultpage');
}

对于 Laravel 4(旧答案)

在给出这个答案时,框架本身没有官方支持。现在您可以使用bgdrl在此方法下方指出的方法:(我尝试更新他的答案,但似乎他不会接受)

在身份验证过滤器上:

// redirect the user to "/login"
// and stores the url being accessed on session
Route::filter('auth', function() {
    if (Auth::guest()) {
        return Redirect::guest('login');
    }
});

登录操作:

// redirect the user back to the intended page
// or defaultpage if there isn't one
if (Auth::attempt(['email' => $email, 'password' => $password])) {
    return Redirect::intended('defaultpage');
}

对于 Laravel 3(甚至更老的答案)

你可以像这样实现它:

Route::filter('auth', function() {
    // If there's no user authenticated session
    if (Auth::guest()) {
        // Stores current url on session and redirect to login page
        Session::put('redirect', URL::full());
        return Redirect::to('/login');
    }
    if ($redirect = Session::get('redirect')) {
        Session::forget('redirect');
        return Redirect::to($redirect);
    }
});
// on controller
public function get_login()
{
    $this->layout->nest('content', 'auth.login'); 
}

public function post_login()
{
    $credentials = [
        'username' => Input::get('email'),
        'password' => Input::get('password')
    ];

    if (Auth::attempt($credentials)) {
        return Redirect::to('logged_in_homepage_here');
    }

    return Redirect::to('login')->with_input();
}

将重定向存储在 Session 上的好处是即使用户错过了键入他的凭据或者他没有帐户并且必须注册,也可以将其持久化。

这也允许除 Auth 之外的任何其他东西在会话上设置重定向,它会神奇地工作。


闪现到会话而不是放置和忘记不是更有意义吗?如果会话中的值存在,您的登录操作只会返回到该值的重定向,否则返回默认页面。
我已经编辑了答案以解释为什么这比 flash 更好。
那讲得通。比每次都重刷好。
当 Auth::attempt() 通过时,您可以简单地将用户重定向到默认页面(通常是他的主页)。该重定向将再次通过该过滤器,并将他重定向到原始请求的 URL(如果有)。否则,它只会继续渲染他的家。我将举一个登录操作的示例。
在 5.1 中,它位于中间件 RedirectIfAuthenticated.php: if ($this->auth->check()) { return redirect('/privatepage'); }
S
Scott Byers

拉拉维尔> = 5.3

5.3 中的 Auth 更改使实现这一点更容易,并且与 5.2 略有不同,因为 Auth 中间件已移至服务容器。

修改新的中间件授权重定向器

/app/Http/Middleware/RedirectIfAuthenticated.php

稍微改变句柄函数,如下所示:

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

    return $next($request);
}

TL;DR 解释

唯一的区别在于第 4 行;默认情况下,它看起来像这样:

return redirect("/home");

由于 Laravel >= 5.3 在检查 Auth Guard 时会自动保存最后一个“预期”路由,因此它变为:

return redirect()->intended('/home');

这告诉 Laravel 在登录前重定向到最后一个预期页面,否则默认转到“/home”或您想发送它们的任何地方。

希望这对其他人有所帮助 - 5.2 和 5.3 之间的差异并不多,特别是在这个领域有很多。


对于 Laravel 6.4,这不再起作用了......有什么想法吗?
我会使用 return redirect()->intended(RouteServiceProvider::HOME); 将您的主路径保留在一个位置。
但在此之前,Laravel 没有任何操作就显示 403 错误页面。相反,如何自动重定向到登录页面,然后到预期页面?
g
giannis christofakis

我发现这两种很棒的方法可能对您非常有帮助。

Redirect::guest();
Redirect::intended();

您可以将此过滤器应用于需要身份验证的路由。

Route::filter('auth', function()
{
    if (Auth::guest()) {
           return Redirect::guest('login');
    }
});

这种方法的基本作用是存储您尝试访问的页面,并将您重定向到登录页面。

用户通过身份验证后,您可以调用

return Redirect::intended();

它会将您重定向到您最初尝试访问的页面。

尽管我通常使用以下方法,但这是一个很好的方法。

Redirect::back()

您可以查看this很棒的博客。


这比上面的解决方案要好得多。上述解决方案需要能够将闭包传递给登录功能,而我在 4.1 中无法做到这一点。但这要简单得多,并且可以按原样工作。
但在此之前,Laravel 没有任何操作就显示 403 错误页面。相反,如何自动重定向到登录页面,然后到预期页面?
d
dabuno

您可以使用 Redirect::intended 功能。它会将用户重定向到他们在被身份验证过滤器捕获之前尝试访问的 URL。如果预期的目标不可用,则可以为此方法提供一个备用 URI。

在登录/注册后:

return Redirect::intended('defaultpageafterlogin');

但在此之前,Laravel 没有任何操作就显示 403 错误页面。相反,如何自动重定向到登录页面,然后到预期页面?
M
MevlütÖzdemir

将您的 LoginControllers 构造函数更改为:

public function __construct()
    {
        session(['url.intended' => url()->previous()]);
        $this->redirectTo = session()->get('url.intended');

        $this->middleware('guest')->except('logout');
    }

它会将您重定向回登录页面之前的页面(返回 2 页)。


唯一对我有用的。这一定意味着我在某个地方发生了另一个重定向,但谁知道在哪里。
在上述所有解决方案中,它对我来说适用于 Laravel 7。很棒的伙伴!
F
Federico Stango

我已经在我的语言选择器代码上使用了一段时间。只要您只需要返回 1 页,它就可以正常工作:

return Redirect::to(URL::previous());

它不是最强大的解决方案,但它超级简单,可以帮助解决一些难题。 :)


是的 previous() 工作正常。但是,如果您的第一次登录失败(因此“登录失败”页面成为您的上一页)并且第二次登录成功,那么您将再次被重定向到登录页面(这可能会将您重定向到主页)。
厉害了哥们!它帮助我节省了时间。
w
whoan
return Redirect::intended('/');

这会将您重定向到项目的默认页面,即起始页面。


y
ymkapuriya

对于 Laravel 8

以下方法适用于 Laravel 8。

基于控制器的方法

/app/Http/Controllers/Auth/AuthenticatedSessionController.php

预登录

预期的 url 将存储在创建时的会话中:

/**
 * Display the login view.
 *
 * @return \Illuminate\View\View
 */
public function create()
{
    session(['url.intended' => url()->previous()]);
    return view('auth.login');
}

登录后

成功登录后,如果会话中提供了预期的 URL,则重定向到它,否则重定向到默认 URL:

/**
 * Handle an incoming authentication request.
 *
 * @param  \App\Http\Requests\Auth\LoginRequest  $request
 * @return \Illuminate\Http\RedirectResponse
 */
public function store(LoginRequest $request)
{
    $request->authenticate();

    //in case intended url is available
    if (session()->has('url.intended')) {
        $redirectTo = session()->get('url.intended');
        session()->forget('url.intended');
    }

    $request->session()->regenerate();

    if ($redirectTo) {
        return redirect($redirectTo);
    }
    return redirect(RouteServiceProvider::HOME);
}

N
Nuruzzaman Milon

对于 laravel 5.* 试试这些。

return redirect()->intended('/');

或者

return Redirect::intended('/');

E
Emile Bergeron

拉拉维尔 3

我稍微调整了您的(Vinícius Fragoso Pinheiro)代码,并将以下内容放在 filters.php

Route::filter('auth', function()
{
    // If there's no user authenticated session
    if (Auth::guest()) {
        // Flash current url to session and redirect to login page
        Session::flash('redirect', URL::full());
        return Redirect::guest('login');
    }
});

然后在我的 AuthController.php 中:

// Try to log the user in.
if (Auth::attempt($userdata)) {

    if ($redirect = Session::get('redirect')) {
        return Redirect::to($redirect);
    } else {
        // Redirect to homepage
        return Redirect::to('your_default_logged_in_page')->with('success', 'You have logged in successfully');
    }
} else {
    // Reflash the session data in case we are in the middle of a redirect 
    Session::reflash('redirect');

    // Redirect to the login page.
    return Redirect::to('login')->withErrors(['password' => 'Password invalid'])->withInput(Input::except('password'));
}

请注意,如果存在身份验证问题,则会重新刷新 'redirect' 会话数据。这样可以在任何登录事故期间保持重定向不变,但如果用户在任何时候点击离开,下一个登录过程不会被会话数据中断。

您还需要在 AuthController 中显示登录表单时重新刷新数据,否则链会中断:

public function showLogin()
{
    // Reflash the session data in case we are in the middle of a redirect 
    Session::reflash('redirect');

    // Show the login page
    return View::make('auth/login');
}

w
whoan

使用Redirect;

然后使用这个:

return Redirect::back();

Y
Yann Boyongo

在 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();
    }

B
Brynn Bateman

这是我对 5.1 的解决方案。我需要有人点击帖子上的“喜欢”按钮,重定向到登录,然后返回原始页面。如果他们已经登录,“Like”按钮的 href 会被 JavaScript 拦截并转换为 AJAX 请求。

该按钮类似于 <a href="/like/931">Like This Post!</a>/like/931 由需要 auth 中间件的 LikeController 处理。

在 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 或您拥有的任何控制器中处理原始页面上按下的按钮的 URL:

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

这种方法超级简单,不需要重写任何现有函数,而且效果很好。 Laravel 可能有一些更简单的方法可以做到这一点,但我不确定它是什么。在我的情况下,使用 intended() 函数不起作用,因为 LikeController 还需要知道前一个 URL 是什么才能重定向回它。本质上是两个级别的向后重定向。


S
Shantha Kumara

对于 Laravel 5.5 和可能 5.4

App\Http\Middleware\RedirectIfAuthenticated 中,将句柄函数中的 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');
}

这样,如果有另一个页面的意图,它将重定向到那里,否则它将重定向到主页。


L
LobsterBaz

Laravel 现在开箱即用地支持此功能! (我相信从 5.5 或更早的版本开始)。

__construct() 方法添加到您的 Controller,如下所示:

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

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

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

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

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

https://laravel.com/docs/5.8/authentication#protecting-routes

也可以通过使用 exceptonly 选项来选择中间件应用到哪个控制器的方法。

except 示例:

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

only 示例:

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

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

https://laravel.com/api/5.8/Illuminate/Routing/ControllerMiddlewareOptions.html#method_except


E
Emmanuel David

如果您使用 axios 或其他 AJAX javascript 库,您可能想要检索 url 并传递给前端

你可以用下面的代码做到这一点

   $default = '/';

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

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

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


A
Arios

您是否在您的 routes.php 中尝试过这个?

Route::group(['middleware' => ['web']], function () {
    //
    Route::get('/','HomeController@index');
});

c
cool programmer
       // Also place this code into base controller in contract function,            because ever controller extends base  controller
 if(Auth::id) {
  //here redirect your code or function
 }
if (Auth::guest()) {
       return Redirect::guest('login');
}

请提供一些评论以与您的代码一起提供一些上下文。谢谢
z
zdorovo

对于 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 中的文件


C
Community

拉拉维尔 5.2

如果您正在使用另一个中间件,例如 Admin 中间件,您可以使用以下内容为 url.intended 设置会话:

基本上我们需要手动设置\Session::put('url.intended', \URL::full());进行重定向。

例子

  if (\Auth::guard($guard)->guest()) {
      if ($request->ajax() || $request->wantsJson()) {
         return response('Unauthorized.', 401);
      } else {
        \Session::put('url.intended', \URL::full());
        return redirect('login');
      }
  }

登录尝试

确保在尝试登录时使用 return \Redirect::intended('default_path');


这就是 redirect()->guest('login') 的用途。
N
Nomi

Larvel 5.3 这实际上对我有用,只需更新 LoginController.php

 use Illuminate\Support\Facades\Session;
 use Illuminate\Support\Facades\URL;


public function __construct()
{
    $this->middleware('guest', ['except' => 'logout']);
    Session::set('backUrl', URL::previous());
}


public function redirectTo()
{
    return Session::get('backUrl') ? Session::get('backUrl') :   $this->redirectTo;
}

参考:https://laracasts.com/discuss/channels/laravel/redirect-to-previous-page-after-login


N
Nayeem Azad

我将以下方法与 Laravel 5.7 的自定义登录控制器和中间件一起使用,但我希望它适用于任何 laravel 5 版本

中间件内部 if (Auth::check()){ return $next($request); } else{ return redirect()->guest(route('login')); }

内部控制器登录方法 if (Auth::attempt(['email' => $email, 'password' => $password])) { return redirect()->intended('/default'); }

如果您需要将意图的 url 传递给客户端,您可以尝试以下操作 if (Auth::attempt(['username' => $request->username, 'password' => $request->password])) { $intended_url=redirect()->intended('/default')->getTargetUrl(); $response = array( 'status' => 'success', 'redirectUrl' => $intended_url, 'message' => '登录成功。你将被重定向到主页..', );返回响应()->json($响应); } else { $response = array( 'status' => 'failed', 'message' => '用户名或密码不正确', );返回响应()->json($响应); }


O
Odilov Oybek

首先,您应该知道如何将用户重定向到“登录”路线:

return redirect()->guest('/signin');

不像这样:

return redirect()->intended('/signin');

M
Marinario Agalliu

这在 laravel 8 中对我有用:

将此添加到您的 LoginController.php:

public function __construct()
{
    session(['url.intended' => url()->previous()]);
    $this->redirectTo = session()->get('url.intended');

    $this->middleware('guest')->except('logout');
}

它会将您重定向 2 次,因此会重定向到您登录前的页面。

归功于@MevlütÖzdemir 的答案!


I
Ismael Padilla

对于 Laravel 5.7,您需要更改为:

中间件>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 是什么? (用户通过返回到此)

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅