如何让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下的控制器里获取不到用户

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
最佳答案

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

3周前 评论
讨论数量: 12

auth.php 中 修改 guardsdriverjwt 试试

3周前 评论
feng_123 (楼主) 3周前
唐章明

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

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,
    ],
];
3周前 评论

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

3周前 评论

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

3周前 评论

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

api
加入中间件

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

也可以使用别名

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

3周前 评论
feng_123 (楼主) 2周前

做不到你说的这个:

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

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

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

3周前 评论
php_yt 2周前
feng_123 (楼主) 2周前

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

2周前 评论

骚操作来了,

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

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 响应,以备后续使用
2周前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!