首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >根据记录的用户字段,在哪里切换到其他服务?

根据记录的用户字段,在哪里切换到其他服务?
EN

Stack Overflow用户
提问于 2022-11-10 06:13:45
回答 1查看 50关注 0票数 0

在laravel 9应用程序中,我尝试切换到不同的服务。

代码语言:javascript
运行
复制
class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        if ($this->app->environment('local')) {
            $this->app->register(\Laravel\Telescope\TelescopeServiceProvider::class);
            $this->app->register(TelescopeServiceProvider::class);

            $this->app->register(\Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class);
        }
        
        // Error pointing at this line
        $loggedUser  = Auth::user();


        if( $loggedUser->membership_mark === 'G') { // G=>Gold Membership
            $this->app->bind('App\Interfaces\PageMembershipMarkStrategyInterface',
                'App\Implementations\PageGoldMemberStrategy');

        }
    }

但我错了:

代码语言:javascript
运行
复制
 Target class [hash] does not exist. in...

看起来,当我需要登录用户时,注册方法并不适合于app->bind。但我要把这个绑在哪里呢?在自定义服务提供商中?我是中间件?

修改块: --我使用命令创建了一个中间件:

代码语言:javascript
运行
复制
php artisan make:middleware SetPageMembershipMarkService

在app/Http/Kernel.php中,我添加了以下内容:

代码语言:javascript
运行
复制
protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,

    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,

    // I added this line : 
    \App\Http\Middleware\SetPageMembershipMarkService::class,

    'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,

但我错了:

代码语言:javascript
运行
复制
Illuminate\Contracts\Container\BindingResolutionException: Target [App\Interfaces\PageMembershipMarkStrategyInterface] is not instantiable while building [App\Http\Controllers\InformOnPageInStockController]....

我不确定必须在Kernel.php的哪个位置添加ref到PageMembershipMarkStrategyInterface?检查日志.我的SetPageMembershipMarkService似乎没有在出错前触发.

修改后的区块2:

在文件app/Http/Kernel.php中,我添加了中间件引用:

代码语言:javascript
运行
复制
protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,

    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,

    // I set it AFTER auth
    'setPageMembership' =>\App\Http\Middleware\SetPageMembershipMarkService::class,

    'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
    'can' => \Illuminate\Auth\Middleware\Authorize::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
    'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    'verified' => \Illuminat`enter code here`e\Auth\Middleware\EnsureEmailIsVerified::class,
];

abd in routes/api.php:

代码语言:javascript
运行
复制
Route::middleware('auth:api')->prefix('v1') /*->name('api.v1')*/ ->group(function () {
    Route::get('/user', function (Request $request) {
        return $request->user();
    });

    ...
    
    Route::middleware(['setPageMembership'])->group(function () {
        Route::resource('/inform-on-page-in-stock', InformOnPageInStockController::class)->except(['edit', 'add']);
   });

我仍然有错误:

代码语言:javascript
运行
复制
Illuminate\Contracts\Container\BindingResolutionException: Target [App\Interfaces\InformOnPageInStockStrategyInterface] is not instantiable while building [App\Http\Controllers\InformOnPageInStockController]. 

  1. 检查日志我找不到在SetPageMembershipMarkService中间件中设置的日志消息,因此看起来它没有在控制器之前设置.怎么了?

你提到的

  1. 使用RouteServiceProvider。哪个语法正确?

文件app/Http/Middleware/SetPageMembershipMarkService.php有以下几行:

代码语言:javascript
运行
复制
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Auth;

class SetPageMembershipMarkService
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse)  $next
     * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
     */
    public function handle(Request $request, Closure $next)
    {

        $loggedUser  = Auth::user();
        \Log::info(varDump($loggedUser, ' -1 SetPageMembershipMarkService $loggedUser::'));

        $membershipMark = $loggedUser->membership_mark;

        if( $membershipMark === 'S') { // G=>Silver Membership
            app()->bind('App\Interfaces\InformOnPageInStockStrategyInterface',
                'App\Implementations\HasNoInformOnPageInStockStrategy');
        }

        if( $membershipMark === 'G') { // G=>Gold Membership
            app()->bind('App\Interfaces\InformOnPageInStockStrategyInterface',
                'App\Implementations\InformOnPageInStockGoldMembersStrategy');
        }

        return $next($request);
    }
}

但是在日志文件中我没有看到在这个中间件中有任何日志消息..。

谢谢!

EN

回答 1

Stack Overflow用户

发布于 2022-11-10 06:27:52

您将无法在Service中获取Auth:user()数据。因为服务提供者在Laravel设置Auth数据之前运行,所以您必须使用一些黑客方法来处理它。

我认为处理与auth相关的数据的更好方法应该是在中间件上,而不是在服务提供者中。

在这个问题上可以找到更多的解释,答案是Laravel - How to get current user in AppServiceProvider

修改块的编辑

您的中间件注册是错误的。

$routeMiddleware此数组用于注册自定义中间件,您将使用该中间件并手动定义

例如:

代码语言:javascript
运行
复制
    protected $routeMiddleware = [
    .....
    // I added this line : 
    'setPageMembership' => \App\Http\Middleware\SetPageMembershipMarkService::class,

然后在路由组中使用这个中间件,如:

代码语言:javascript
运行
复制
Route::middleware(['auth', 'setPageMembership'])->group(function () {
    Route::get('test', [TestController::class, 'test']);
});

如果您希望中间件为所有路由运行,最好将其添加到$middleware数组中,或者如果您希望在特定的路由组(web/api)中运行,则在$middlewareGroups单个webapi数组中添加它。

如果您希望每个路由都有中间件,那么在RouteServiceProvder中添加中间件也是有效的。

但是,对于用例,在绑定之前需要进行身份验证。因此,在执行这些绑定操作之前,需要先启动auth中间件。因此,将中间件添加到您的路由文件中,如我前面所示,对于您的用例来说就足够了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74384830

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档