Laravel 登录之后,跳转回登录前的页面

更新日期: 2019-01-04 阅读次数: 11879 分类: Laravel

场景

我自定义了一套 laravel 的登录逻辑,使用手机号加验证码登录,没有使用 laravel 内置的登录逻辑。

实现方法

先列一下解决方法,然后再一一说明。

例如,如果购物车页面需要登录之后才能访问,并且点击购物车,弹出登录页面,完成登录之后,需要跳回到购物车页面。

首先需要在 route 上加上权限控制。

Route/web.php

Route::get('cart', [
    'uses' => 'CartController@cart_index',     // 购物车页面
])->middleware('auth');

在 web.php 内的 route 不需要再单独加上一层 web group。

同时给 login 路由设置一个 name,为 login。否则 auth middleware 会报错:local.ERROR: Route [login] not defined

Route::get('/login', [
    'uses' => 'LoginController@index',
    'as' => 'login',
]);

在 LoginController 中,Login 验证完成之后,跳转逻辑修改为

return redirect()->intended();

好了,这样就可以了。

下面记录一些细节的说明。

session

https://laravel.com/docs/5.5/session

Since HTTP driven applications are stateless, sessions provide a way to store information about the user across multiple requests.

两种调用方法:

第一种,通过 request

$value = $request->session()->get('key', 'default');

第二种,使用 global session helper

$value = session('key', 'default');

url()->previous()

https://laravel.com/docs/5.5/urls

// Get the current URL without the query string...
echo url()->current();
// Get the current URL including the query string...
echo url()->full();
// Get the full URL for the previous request...
echo url()->previous();

但是,需要注意的是 url()->previous() 在实际运行中,并没有被用到。真正被用到的是 url.intended。

测试一下,在 login 登录页面

\Log::info(url()->previous());
\Log::info(session('url.intended'));

local.INFO: http://localhost:8000/
local.INFO: http://localhost:8000/cart

会看到,url()->previous() 得到的是被 route auth 拦住的之前的页面,而不是拦住将去往的页面,后者才是我们想获取到的。

url.intended

我并没有找到官方的文档,于是搜索了一下代码

grep "url\.intended" -r vendor/laravel
vendor/laravel/framework/src/Illuminate/Routing/Redirector.php:        $this->session->put('url.intended', $this->generator->full());
vendor/laravel/framework/src/Illuminate/Routing/Redirector.php:        $path = $this->session->pull('url.intended', $default);

Redirector.php

    /**
     * Create a new redirect response, while putting the current URL in the session.
     *
     * @param  string  $path
     * @param  int     $status
     * @param  array   $headers
     * @param  bool    $secure
     * @return \Illuminate\Http\RedirectResponse
     */
    public function guest($path, $status = 302, $headers = [], $secure = null)
    {
        $this->session->put('url.intended', $this->generator->full());

        return $this->to($path, $status, $headers, $secure);
    }

    /**
     * Create a new redirect response to the previously intended location.
     *
     * @param  string  $default
     * @param  int     $status
     * @param  array   $headers
     * @param  bool    $secure
     * @return \Illuminate\Http\RedirectResponse
     */
    public function intended($default = '/', $status = 302, $headers = [], $secure = null)
    {
        $path = $this->session->pull('url.intended', $default);

        return $this->to($path, $status, $headers, $secure);
    }

url.intended 会记录 login 后将要跳转的 URL。

redirect()->intended('dashboard')

https://laravel.com/docs/5.5/authentication

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

Intended 函数的定义参考上面 Redirector.php 中的实现。

所以等同于自己手写这个逻辑。

在 LoginController 中,增加设置跳转页面的逻辑。

public function index()
{
    if(!session()->has('url.intended'))
    {
        session(['url.intended' => url()->previous()]);
    }
    return view('login');    
}

Login 验证完成之后,跳转逻辑修改为

return redirect(session('url.intended', '/'));

middleware 来处理大量的路由

如果有大量的页面需要登录后才能访问,那么在 controller 中去逐个处理是否登录逻辑就非常浪费时间,简洁的实现方式是使用 middleware。

如果需要跳转到一个自定义的 login 页面

https://laracasts.com/discuss/channels/laravel/custom-login-page-redirection-from-middleware

新建一个 middleware:

class AuthMiddleware
{
    public function handle($request, Closure $next)
    {
        if (auth()->guest()) {
            return redirect()->route('login.create');
        }
        return $next($request);
    }
}

App\Http\Kernel.php:

protected $routeMiddleware = [
    'auth.custom' => \App\Http\Middleware\AuthMiddleware::class,
    ....

参考

https://stackoverflow.com/questions/29954791/laravel-5-after-login-redirect-back-to-previous-page

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式