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

时间:2013-03-13 15:40:59

标签: laravel laravel-4

这似乎是一个非常基本的流程,Laravel有很多很好的解决基本的东西,我觉得我错过了什么。

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

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

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

25 个答案:

答案 0 :(得分:217)

对于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之外的任何其他东西在会话上设置重定向,它会神奇地工作。

答案 1 :(得分:54)

Laravel> = 5.3

5.3中的Auth更改使得实现更容易,因为Auth Middleware已经移动到服务容器,因此与5.2略有不同。

修改新的中间件身份验证重定向程序

/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之间的区别并不多,特别是在这方面还有不少。

答案 2 :(得分:25)

我发现这两种方法可能对你非常有帮助。

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

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

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

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

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

return Redirect::intended();

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

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

Redirect::back()

您可以查看this精彩的博客。

答案 3 :(得分:20)

您可以使用重定向::预期功能。它会将用户重定向到他们在被authenticaton过滤器捕获之前尝试访问的URL。可以为此提供回退URI 预期目标不可用的方法。

在登录后/注册:

return Redirect::intended('defaultpageafterlogin');

答案 4 :(得分:11)

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

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

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

答案 5 :(得分:8)

将LoginControllers构造函数更改为:

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

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

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

答案 6 :(得分:8)

return Redirect::intended('/');

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

答案 7 :(得分:6)

对于laravel 5. *尝试这些。

return Redirect::intended('/');

<select size="6" multiple="multiple" >
    <option value="1">Id</option>
    <option value="2">Subject</option>
    <option value="3">Status</option>
    <option value="4">Assignment</option>
    <option value="5">LastCreatedBy</option>
</select>

答案 8 :(得分:5)

Laravel 3

我略微调整了您的(ViníciusFragosoPinheiro)代码,并将以下内容放在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');
}

答案 9 :(得分:3)

使用Redirect;

然后使用:

return Redirect::back();

答案 10 :(得分:1)

对于 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');
}

登录后

成功登录后,如果会话中存在可用的预期网址,则重定向到该网址,否则重定向到默认网址:

/**
 * 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);
}

答案 11 :(得分:0)

这在laravel 8中对我有用:

将此添加到您的LoginController.php:

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

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

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

要前往答案,请@MevlütÖzdemir!

答案 12 :(得分:0)

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

答案 13 :(得分:0)

如果您使用的是axios或其他AJAX javascript库,则可能要检索网址并传递到前端

您可以使用以下代码进行操作

   $default = '/';

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

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

这将返回json格式的字符串

答案 14 :(得分:0)

✓ 在 Laravel 7.x 上测试

转到 LoginController.php 并添加以下代码:

public function showLoginForm() {
        
  if(!session()->has('url.intended')) {

      $prev = url()->previous();
      $url_one = 'your url';         
      $url_two = 'your second url';

      if ($prev == $url_one OR $prev == $url_two) {
         session(['url.intended' => 'dashboard']);
      } else {
         session(['url.intended' => url()->previous()]);
      }
  }

  return view('auth.login');
}

此函数将设置 url.intended 会话变量。 Laravel 使用此变量查找用户登录后将被重定向到的页面。

我添加了一个额外条件,如果用户不是来自 $url_one$url_two,它将重定向到预览位置。在我的情况下,如果用户以前在那里,我不希望用户被重定向回自己的家。我更喜欢用户是否转到仪表板。如果他在用户页面上,那么重定向回来是有意义的。

答案 15 :(得分:0)

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

"query": {
    "range": {
        "myfield": {
            "gte": 0.6666
        }
    }
}

不是这样的:

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

答案 16 :(得分:0)

Laravel现在可以立即使用此功能! (我相信从5.5或更早版本开始)。

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

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

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

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

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

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

奖金: 通过使用exceptonly选项,也可以选择中间件适用于哪种控制器的方法。

except的示例:

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

only的示例:

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

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

答案 17 :(得分:0)

我正在将以下方法与用于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');
    }
    
  • 如果您需要将目标网址传递给客户端,则可以尝试以下

       if (Auth::attempt(['username' => $request->username, 'password' => $request->password])) {
           $intended_url= redirect()->intended('/default')->getTargetUrl();
           $response = array(
          'status' => 'success',
          'redirectUrl' => $intended_url,
          'message' => 'Login successful.you will be redirected to home..', );
          return response()->json($response);
        } else {
            $response = array(
          'status' => 'failed',
          'message' => 'username or password is incorrect', );
         return response()->json($response);
        }
    

答案 18 :(得分:0)

对于Laravle 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);
    }
  

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

答案 19 :(得分:0)

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');
}

这种方式如果有另一个页面的意图,它将重定向到那里,否则它将重定向回家。

答案 20 :(得分:-1)

Laravel 5.2

如果您使用的是其他中间件,例如管理中间件,则可以使用以下内容为 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');

答案 21 :(得分:-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

中的文件

答案 22 :(得分:-1)

这是我的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是重定向到它的。基本上是两级重定向。

答案 23 :(得分:-1)

       // 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');
}

答案 24 :(得分:-1)

您是否在routes.php中尝试过此操作?

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