V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
selfcreditgiving
V2EX  ›  问与答

请教各位 Laravel 大神, api routes 加上 middleware 后,为什么就会被重定向到 home 页?

  •  
  •   selfcreditgiving · 2019-08-26 14:34:15 +08:00 · 1665 次点击
    这是一个创建于 1676 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有一个 testProcedure 的路由,放在 api route 里会自动跳转到 /home。

    route 里加了两个 middleware,一个是默认的 Laravel 的 Auth (用户登录),
    还有一个是自己定义的(用户角色权限的验证模块)

    同样两个 middleware, 写在 web.php ( web 路由)里是可以正常运行的,
    写在 api.php ( api 路由)里就会被重定向到 /home (home 页),
    这个 testProcedure 路由不用 middleware 包裹(不经过 middleware ),是可以正常访问的,
    所以问题可能就出在 middleware 这上面。

    各位大佬知道是啥原因吗

    这是路由的代码:

    /routes/web.php

    // 所有 route 都需要经过两步认证:用户登录认证、角色权限检测。
    Route::group(['middleware' => ['auth','isRole']], function () {
    
        Route::get('/testProcedure','AccountController@testProcedure');
    
    });
    
    Auth::routes();
    

    /routes/api.php

    <?php
    
    
    // 所有 route 都需要经过两步认证:用户登录认证、角色权限检测。
    Route::group(['middleware' => ['auth','isRole']], function () {
        Route::get('/testProcedure','AccountController@testProcedure');
    
    });
    
    Auth::routes();
    

    /app/Http/Controllers/AccountController.php (只是打印时间)

        public function testProcedure(Request $request)
        {
    
            $date = date('Y-m-d H:i:s');
    
            dd($date);
        }
    

    在 web 路由里定义的地址是: localhost/testProcedure
    在 api 路由里定义的地址是: localhost/api/testProcedure (laravel 默认会加上 api/ 前缀)

    第 1 条附言  ·  2019-08-26 15:06:34 +08:00

    自定义的 isRole middleware代码也添加一下:

    <?php
    
    namespace App\Http\Middleware;
    
    use Closure;
    use Illuminate\Support\Facades\Auth;
    use Illuminate\Support\Facades\DB;
    use App\OwnClasses\Permission;
    
    class RoleMiddleware
    {
        /**
         * Handle an incoming request.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  \Closure  $next
         * @return mixed
         */
        public function handle($request, Closure $next)
        {
            $route = $request->route()->uri;
            if (!Permission::isRouteAuthorized($route)) {
                if ($request->ajax()) {
                    return response('have no permission.', 403);
                } else {
                    return redirect('/'); // set here any url you need
                }
            }
    
            return $next($request);
        }
    }
    
    
    第 2 条附言  ·  2019-08-26 17:13:16 +08:00
    @tongz
    >\app\Http\Middleware\Authenticate.php 里面改掉试下

    没有找到 Authenticate.php ,这个路径下有一个 /app/Http/Middleware/RedirectIfAuthenticated.php

    现在 laravle 版本是:"laravel/framework": "5.5.*"

    /app/Http/Middleware/RedirectIfAuthenticated.php

    ```php
    <?php

    namespace App\Http\Middleware;

    use Closure;
    use Illuminate\Support\Facades\Auth;

    class RedirectIfAuthenticated
    {
    /**
    * Handle an incoming request.
    *
    * @param \Illuminate\Http\Request $request
    * @param \Closure $next
    * @param string|null $guard
    * @return mixed
    */
    public function handle($request, Closure $next, $guard = null)
    {
    if (Auth::guard($guard)->check()) {
    return redirect('/home');
    }

    return $next($request);
    }
    }

    ```
    第 3 条附言  ·  2019-08-26 18:07:41 +08:00

    找到一个答案,https://stackoverflow.com/questions/44861937/laravel-api-routes-with-auth
    里面说 laravel 的 api routes 默认使用 token 验证,不像web routes 那样使用 session。

    之前试过 用JWT 的话就可以用 api routes
    还是不搞了,只是想用到 api routes 自动添加 "api/" 前缀这个功能,不用弄的太麻烦。

    13 条回复    2019-08-26 17:44:58 +08:00
    Woood
        1
    Woood  
       2019-08-26 14:36:52 +08:00
    所以问题可能就出在 middleware 这上面。 然后你就是不贴 middleware 的代码是吧
    mokeyjay
        2
    mokeyjay  
       2019-08-26 14:49:39 +08:00
    全局搜索 /home 有惊喜
    selfcreditgiving
        3
    selfcreditgiving  
    OP
       2019-08-26 15:01:45 +08:00
    @Woood 不好意思啊。自定义的 角色权限验证 middleware 很简单,我也贴上

    ```php
    <?php

    namespace App\Http\Middleware;

    use Closure;
    use Illuminate\Support\Facades\Auth;
    use Illuminate\Support\Facades\DB;
    use App\OwnClasses\Permission;

    class RoleMiddleware
    {
    /**
    * Handle an incoming request.
    *
    * @param \Illuminate\Http\Request $request
    * @param \Closure $next
    * @return mixed
    */
    public function handle($request, Closure $next)
    {
    $route = $request->route()->uri;
    if (!Permission::isRouteAuthorized($route)) {
    if ($request->ajax()) {
    return response('have no permission.', 403);
    } else {
    return redirect('/'); // set here any url you need
    }
    }

    return $next($request);
    }
    }

    ```

    代码中的 Permission::isRouteAuthorized() 就不写进来了,如果当前登录用户有权限的话,会返回 true,否则 返回 false。
    selfcreditgiving
        4
    selfcreditgiving  
    OP
       2019-08-26 15:02:46 +08:00
    回复不可以 用 markdown ? ,代码好乱啊
    figurant
        5
    figurant  
       2019-08-26 15:41:40 +08:00
    打断点,debug 啊
    ss098
        6
    ss098  
       2019-08-26 16:12:13 +08:00
    我记得 Laravel 的 Auth Middleware 的默认跳转地址就是 home,你可以全局搜索 home 来替换掉这个地址。
    selfcreditgiving
        7
    selfcreditgiving  
    OP
       2019-08-26 16:12:43 +08:00
    @figurant 请问 laravel 也可以打断点调试吗,用的是 phpstorm,一直用 dd() dump() 这样调试的
    ss098
        8
    ss098  
       2019-08-26 16:15:50 +08:00
    详见 Laravel 官方文档的 Security -> Authentication 的 “ Path Customization ” 一节(不让我发链接),定义 $redirectTo 属性。
    tongz
        9
    tongz  
       2019-08-26 16:32:53 +08:00
    \app\Http\Middleware\Authenticate.php 里面改掉试下
    selfcreditgiving
        10
    selfcreditgiving  
    OP
       2019-08-26 17:08:01 +08:00
    @ss098 @Woood @figurant @mokeyjay 我用 把变量打印到 laravel.log 日志里的方法 测试了下,发现 api/testProcedure 根本就没有通过自定义的 “ isRole ” middleware,应该是在 “ auth ” 那个 middleware 就没有通过。

    请问 auth middleware 的代码路径放在哪里呢?

    我试了下把 isRole 这个 middleware 去掉,也是同样的,被跳转到 /home ( / 和 /home 应该会相互跳转吧)
    注:下面的 'middleware' => ['auth', 'isRole'] 改为了 'middleware' => ['auth']

    ```php

    <?php

    use Illuminate\Http\Request;



    Route::middleware('auth:api')->get('/user', function (Request $request) {
    return $request->user();
    });


    // 所有 route 都需要经过两步认证:用户登录认证、角色权限检测。
    Route::group(['middleware' => ['auth']], function () {
    Route::get('/testProcedure','AccountController@testProcedure');
    });

    Auth::routes();

    ```
    Woood
        11
    Woood  
       2019-08-26 17:13:17 +08:00
    App\Http\Middleware\Authenticate 里面不就有 return route('token');
    figurant
        12
    figurant  
       2019-08-26 17:39:17 +08:00
    你中间件注册没用
    selfcreditgiving
        13
    selfcreditgiving  
    OP
       2019-08-26 17:44:58 +08:00
    @figurant 已经在 /app/Http/Kernel.php 里注册了

    protected $routeMiddleware = [
    'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
    'can' => \Illuminate\Auth\Middleware\Authorize::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    'isRole' => \App\Http\Middleware\RoleMiddleware::class,
    'cors' => \Barryvdh\Cors\HandleCors::class,
    ];
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1657 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 16:47 · PVG 00:47 · LAX 09:47 · JFK 12:47
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.