订阅者中间件路由允许公众查看所有受限页面

Posted

技术标签:

【中文标题】订阅者中间件路由允许公众查看所有受限页面【英文标题】:Subscriber middleware route allowing public to view all restricted pages 【发布时间】:2021-05-19 07:22:55 【问题描述】:

我的项目中的路由和中间件有问题。我有一个仅对订阅者锁定的主题列表。但是,主题可以标记为公开,允许访客用户/公众查看主题。

我面临的问题是我要么让所有主题都对公众可见,要么没有。

我有以下订阅者中间件。

public function handle(Request $request, Closure $next)

    if ( $request->user() && ! $request->user()->subscribed('annual_membership') ) 
        return redirect('profile');
     
        
    if( Auth::Guest() ) 
        return redirect('topics')->with('error', 'You need to be a registered memeber to view this topic.');
    

    return $next($request);

这是像这样添加到我的内核中的。

protected $routeMiddleware = [
    // ...
    'subscriber' => \App\Http\Middleware\Subscriber::class,
];

然后我设置了以下路线。

Route::get('voting-topics', [TopicController::class, 'topics'])->name('topics');
Route::get('voting-topics/topic', [TopicController::class, 'topic'])->name('topic');

Route::group(['middleware' => ['subscriber']], function () 

    Route::get('profile/billing', function (Request $request) 
        return $request->user()->redirectToBillingPortal();
    );

    Route::get('voting-topics/topic', [TopicController::class, 'topic'])->name('topic');
);

还有我的主题控制器。

class TopicController extends Controller

    public function topics(Request $request) 
    
        if ( $request->user() && $request->user()->subscribed('annual_membership') ) 
            return $this->subscriberTopics();
         else 
            return $this->publicTopics();
        
    
    
    
    private function publicTopics() 
    
        $topics = Topic::orderBy('date', 'asc')->where('free_to_view', 1)->paginate(50);

        return view('topics.topics', compact('topics'));
    
    
    private function subscriberTopics() 
    
        $topics = Topic::orderBy('date', 'desc')->paginate(50);

        return view('topics.topics', compact('topics'));
    

    public function topic(Request $request, Topic $topic) 
    
        $topic = Topic::find($topic)->first();

        return view('topics.topic', compact(['topic',));
    

主题目录工作正常。它只显示标记为公开的主题和订阅者的所有主题。我的代码目前只允许订阅者查看所有主题,而访客可以看到公共主题,这不是我想要的。

如果我删除中间件路由,相反的情况是访客可以访问所有主题,如果他们输入主题的 URL。

编辑

为了更好地澄清和解释,我有一个主题列表(基本上就像博客文章)。主题仅供我网站的付费订阅者查看。但是,有些主题可以标记为免费查看,并且所有人都可以看到。

如果我访问 example.com/voting-topics,那么我只会看到免费主题。 (这是正确且有效的)如果我登录并转到相同的 URL,我会看到所有主题,因为我已登录,并且我是付费订阅者。 (这又是正确且有效的)

如果我删除了中间件中的重复路由,则直接通过 URL 转到 example.com/voting-topics/123 或任何其他主题 ID。我可以查看该主题,即使它应该只对订阅者锁定。

如果我将重复的路由添加回我的中间件,公众将无法访问免费主题。

我需要访客/普通公众/非订阅者仅访问标记为公开但付费订阅者可以访问所有主题的主题。 `

【问题讨论】:

第一个问题,你有 2 个同名路由(一个有中间件,一个没有)。其次,您能否更好地描述一下没有按预期工作的地方。 @Bart 我已经更新了这个问题,提供了更多关于我想要做什么的信息 【参考方案1】:

所以看来这毕竟是一个简单的修复,而不是在我的路线中进行检查,我需要在我的控制器中进行。

我从我的中间件中删除了Route::get('voting-topics/topic', [TopicController::class, 'topic'])->name('topic');,然后在我的控制器中添加了以下代码。

if( $topic->free_to_view === 1 || Auth::check() && auth()->user()->subscribed('annual_membership')) 
    return view('topics.topic', compact('topic'));

 else 

    return redirect()->back()->with('error', 'You need to be a paying member to view this topic');


【讨论】:

这样你就完全绕过了订阅者中间件,我认为这是你要走的路,但无论如何很高兴听到我的提示让你走上了正轨。

以上是关于订阅者中间件路由允许公众查看所有受限页面的主要内容,如果未能解决你的问题,请参考以下文章

你好,请问微信如何开启订阅号的新消息提醒?不用点进去订阅号才能看

微信公众号订阅的合集在哪里看

RabbitMQ 一二事 - 订阅模式(微信公众号模式)的应用

Symfony:事件订阅者。当路由要求用户必须经过身份验证时触发 404 页面(取决于 .env var)

如何实时接收微信订阅号的更新提醒?

阻止 RBAC 继承