如何让api和web端的登录状态可以共享呢

1. 运行环境#

1). 当前使用的 Laravel 版本?#

laravel5.5

2). 当前使用的 php/php-fpm 版本?#

PHP 版本:7.1

php-fpm 版本:7.1

3). 当前系统#

centos 7.6

4). 业务环境#

开发环境

5). 相关软件版本#

2. 问题描述?#

api 接口使用的是 tymon/jwt-auth 做的 token 验证登录
web 端还是用的原生的 session 登录
想实现当调用 api 接口登录的时候,web 端也能同步登录状态(代码在同一个域名下)

3. 您期望得到的结果?#

共享登录状态

4. 您实际得到的结果?#

我在 api 接口登录的时候调用 Auth::attempt ($credentials) 或者 Auth::login ($user) 登录,在 api 接口打印 Auth::user () 可以获取到用户,但是在 web.php 下的控制器里获取不到用户

《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
最佳答案

直接给 api 添加 web 中间件就行了。

1个月前 评论
讨论数量: 12

auth.php 中 修改 guardsdriverjwt 试试

1个月前 评论
feng_123 (楼主) 1个月前
唐章明

可以实现,但是你要先说明你是要谁共享谁

API 共享给 web

比如你的 APP 使用 api 登录,在 APP 里打开网页,要自动登录,可以把 token 放在 header 头,web 端搞一个中间件,从 token 读取 id 再调用 Auth::onceUsingId (your uid) 即可。

web 共享给 API

如果你是指 web 站点登录,并且你的 web 站点会调用 /api/* 下的路由,你希望 api 下的路由方法与 web 使用相同的登录态

  • 方案 1、路由不要放在使用 routes/api.php,写在 routes/web.php 里面
  • 方案 2、新增路由文件,以 laravel12 举例
// project\bootstrap\app.php

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        api: __DIR__.'/../routes/api.php',
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        then: function () {

            // 注册webapi路由
            Route::middleware('web')
                ->prefix('/api') // 建议直接用 /web-api 开头和客户端api区分开
                ->name('webapi.')
                ->group(base_path('routes/webapi.php'));
        },
    )
    ...

自带的那个 routes/api.php 没办法和 web 共用登录态的,因为它就没启用 session,你只能单独搞一个路由文件,也用 /api 开头,必须用 web 中间件,因为这个中间件才开启了 session,参考如下

/**
 * 自带中间件组
 *
 * @var array
 */
protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,  // cookie加密
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,  // 追加在response之前设置的cookie
        \Illuminate\Session\Middleware\StartSession::class,  // 开启session
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,  // 表单错误共享到模板
        \App\Http\Middleware\VerifyCsrfToken::class,   // csrf防护
        \Illuminate\Routing\Middleware\SubstituteBindings::class,  // 路由绑定到模型
    ],

    'api' => [
        \Illuminate\Routing\Middleware\ThrottleRequests::class.':api',  // 访问限速
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
];
1个月前 评论

直接给 api 添加 web 中间件就行了。

1个月前 评论

\App\Http\Middleware\EncryptCookies::class, //cookie 加密 \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, // 追加在 response 之前设置的 cookie \Illuminate\Session\Middleware\StartSession::class, // 开启 session

1个月前 评论

如果要 api 登录 web 也登陆 就要 开启 api 的 session 就在 api 登录 route 加入 中间件

api
加入中间件

\Illuminate\Session\Middleware\StartSession::class,

也可以使用别名

然后 对应 api 登录逻辑中 加入 api 和 web 守卫 的登录

1个月前 评论
feng_123 (楼主) 1个月前

做不到你说的这个:

想实现当调用 api 接口登录的时候,web 端也能同步登录状态(代码在同一个域名下)

你 api 登录接口是给软件用的吧,如果是的话:
除非在软件端点击链接跳转到浏览器(携带 jwt),浏览器实现自动登录(写自动登录逻辑)。

这种逻辑来实现 web 的自动登录

1个月前 评论
php_yt 1个月前
feng_123 (楼主) 1个月前

用 cookie 就行 , api 和 web 都走 cookie 。我的理解是你的 api 应该是走了 js 从 localstorage 。 我的 gooseforum.online 就是走的 cookie, api 登陆的时候也是返回设置 cookie, 前后分离的接口和 web 都可以验证登陆态

1个月前 评论

骚操作来了,

加个中间件,判断是否登录,没有登录就验证去登录

jwt 请求(携带 cookie) -》 中间件判断 web 是否登录,没有 接登录

web 请求(携带 cookie, jwt 如有) -> 不带 jwt,生成新的

// ajax 或放到网页中, 让js 读取
ajax:   ['code' => 0, 'data' => 'xxx',  'jwt' => xxxx],  js 通用函数接受处理
网页: var jwt = {xxx};   如保存到 localStorage,用的时候读取

jQuery.ajaxSetup() // 设置jwt请求头
$(document).ajaxSuccess(function() {}); // 处理jwt 响应,以备后续使用
1个月前 评论