这似乎是一个相当基础的流程,而且 Laravel
有许多好的解决方案来处理基本的事情,我觉得我可能遗漏了什么。
用户点击需要身份验证的链接。 Laravel 的 auth 过滤器启动并将用户路由到登录页面。 用户登录后,再次访问之前被“auth”过滤器拦截的原始页面。
有没有一种很好的方法可以知道他们最初想要进入哪个页面?由于 Laravel 拦截请求,我不知道它是否在某处记录以便用户登录后轻松路由。
如果没有,我很想听听你们中的一些人如何手动实现这一点。
使用Redirect;
指令
然后使用以下命令:
return Redirect::back();
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();
}
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 是什么才能重定向回去。本质上是两个级别的后退重定向。
auth
中间件附加到您的原始链接上,就可以非常简单地进行操作。当用户成功通过中间件检查(表示他们已登录)时,他们会自动重定向到所需的目的地。例如,您可以这样做,而不是在控制器中检查身份验证。Route::get('/appointments',[AppointmentsController::class,'appointments'])->middleware(['auth'])->name('appointments');
现在是2022年9月,我想分享一下我为OP的问题所做的事情。请对我宽容,我还是个新手。
我的问题:在我实现了MustVerifyEmail
之后,上面的解决方案不起作用了。我使用的是Laravel 6.x。
所以,在整整一个晚上的头痛和无数杯咖啡的帮助下,终于现在它可以工作了。这不是新的解决方案,因为它是从之前的答案修改而来的。
第一步:
意识到:具有名称'url.intended'
的会话已经被vendor\laravel\framework\src\Illuminate\Routing\Redirector.php
占用了。
所以我选择使用不同的会话名称:'url_intended'
第二步:
添加这行代码:
session(['url_intended' => url()->previous()]);
<?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\LoginController
或app\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,
];
针对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);
}
showLoginForm()
函数:public function showLoginForm()
{
if(!session()->has('url.intended'))
{
session(['url.intended' => url()->previous()]);
}
return view('auth.login');
}
这样就可以重定向到另一个页面,否则会重定向到主页。
Laravel现在支持这个功能,开箱即用! (我相信自5.5或更早以来就开始支持了)。
按照下面所示,在Controller
中添加一个__construct()
方法:
public function __construct()
{
$this->middleware('auth');
}
登录后,您的用户将被重定向到他们最初想要访问的页面。
您还可以根据应用程序逻辑添加Laravel的电子邮件验证功能:
public function __construct()
{
$this->middleware(['auth', 'verified']);
}
文档中包含一个非常简短的示例:
还可以使用 except
或 only
选项来选择中间件应用于哪个控制器的方法。
使用 except
的示例:
public function __construct()
{
$this->middleware('auth', ['except' => ['index', 'show']]);
}
使用only
的示例:
public function __construct()
{
$this->middleware('auth', ['only' => ['index', 'show']]);
}
有关 except
和 only
中间件选项的更多信息:
$default = '/';
$location = $request->session()->pull('url.intended', $default);
return ['status' => 200, 'location' => $location];
针对 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上的文件替换它。
对于 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