记接口当中使用 session 是如何被排斥的

第一次在 Laravel 的接口当中使用 Session,受到成吨的伤害。
话不多说,直奔主题吧。
使用的代码是刚通过 composer create-project --prefer-dist laravel/laravel blog 安装的。
首先先来调用下 Session,路由为 api.php 中的接口路由,并在首页 welcome.blade.php 中使用 JQuery$.get() 来访问下该接口。
file
file
访问下看是否设置成功。
file
这样应该是设置成功了吧,再加点判断,看下客户端能不能找到 Session
file
看下结果。
file
What ?为啥没找到我的我名字呢?通过读文档知道还有另一种写法,我们再来尝试下看看。
file
再看下结果。
file
Emmmm...直接报错了,有点过分了吧。直接 Google 报错信息发现,Laravel 中的 Session 被封装了,要使用 Session 必需要开启 Session 中间件。而默认 api 中没有开启该中间件,如下图所示。
file
大家有没有在 web 中看到 \Illuminate\Session\Middleware\StartSession::class 这个中间件,从字面意思应该很清楚了吧?这个就是开启 Session 的中间件,让我们加在下面的 api 中再尝试下。
file
没报错了,但是好像还是获取不到上一次请求设置的 Session 啊,灰常尴尬。让我们从客户端获取服务端 Session 的原理开始思考,大家应该都知道,Session 在设置时,会伴随 Cookie 在客户端的生成,当客户端请求时会带上设置好的 Cookie ,一般存的是 session_id,服务端拿到这个 session_id 后就能顺利拿到 Session。那我们能设置只是找不到,会不会是 Cookie 出错了呢?所以让我们看看接口响应的 Cookie。(PS:我设置了 .env 中的 SESSION_LIFETIME 为24小时,这里就不多赘述了,并且为了区别,我设置了 APP_NAMEtest 以区分 Laravel 自己生成的 Cookie)
file
这里主要看是否有 ValueExpires,都有值且过期时间为1天,不存在秒过期的情况。那是为什么呢?
各位,请仔细看 Request 中的 Cookie 与响应 ResponseCookie,有没有发现 Value 有很明显的差别,完全不像是一个应用生成的 Cookie,并且当你刷新页面时原本 Request 中的 test_session 应该替换为上一次请求中的 Response 中的 test_session,这样就能找到之前设置好的 Session 了,但实际是又重新生成了一个不同的 Cookie。那么问题很明显了,设置 Session 返回的 Cookie 是有误的,导致框架每次加载时,判断这个 Cookie 为无效的并重新生成了一个新的,所以找不到之前的 Session
让我们又回到中间件那里。
file
我在 web 中又发现一个 \App\Http\Middleware\EncryptCookies::class,字面意思,一个 Cookie 加密中间件。好像跟我们的问题有关系诶,我已经将它添加到 api 中,我们再试一下。
file
哎哟,终于好了,接口里面使用 Session 就这样被排斥吗 :cry:

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 15
你看我吊吗啊

api不应该使用session。。

5年前 评论

@JeffLi 我只是单纯的在论述这么一个问题,不是说一定要在接口中使用session。而且单纯做 web 的接口使用 session 也是可以的,更何况 session_id 也同样能作为 token

5年前 评论

@JeffLi 能否说下原因呢.这个问题也困扰了我很久...为何....

5年前 评论
你看我吊吗啊

@韩槑槑 嗯 ,我看得出来

5年前 评论

@落伽 因为接口作用之一就是提供给多端使用,而除了 web 端之外的都不使用 session,比如 App

5年前 评论
你看我吊吗啊

@落伽 博主说的是恰当的,web中自然是可以使用session,如果在app的api 中qui使用session.... 反正我做了两年多是没用过这种操作,准确的原因我也不清楚,只是一个约定俗成的习惯,都是用token

5年前 评论

@JeffLi 我文章里面有说到,服务端之所以能找到 session,是因为在生成 session 的时候同时在客户端生成了相应的 cookie,浏览器会在下次请求时在请求头中带上 cookie,这样就能找到 session,而 app 不会自己带上 cookie,也就不能找到 session 了。除非你每次请求时手动带上 sessionid 或 cookie。但是与其这样还不如直接用 token。

5年前 评论

session 需要在请求头里面带 session_id 这个参数要确定当前请求对应的 session , 然后API请求是无状态的, 所以, 我们在API里面不能, 注意不是不应该, 而是不能 使用session(虽然通过某些方法可以使用)

5年前 评论
你看我吊吗啊

@韩槑槑 :ok_hand: 感谢指导!

5年前 评论
你看我吊吗啊

@韩槑槑 我看有大佬说session是基于cookie的?

5年前 评论

@JeffLi 是的,在基本的session原理是基于cookie的,因为cookie存的就是session_id。当你不想用 cookie 时,可以手动在请求中加上 session_id。别谈论这个了,我只是单纯的说出发现的这么一个问题。?

5年前 评论
你看我吊吗啊

@韩槑槑 顺带了解一下冷知识 嘿嘿嘿

5年前 评论
leo

对于你这个需求,直接把 api 路由放 web.php 里面即可,而不是 api.php

5年前 评论

@leo 我正在尝试,也想了好多办法,就是不行。跟楼主正好相反,他是api路由去获取session。我是使用curl发送到指定的api路由里,这个方法里进行存储session 信息。但是当刷新网站时,就没有了。api:session、cookie都加了,甚至设置了session.php 文件中的 .***.com 跨域问题。始终没有实现!请指教啊。头疼了一天了!

4年前 评论

curl 到laravel 的api或web, 进入方法后无法存入session ,有大佬知道什么原因吗? api 也加入了session 着急想解决这个问题,可以红包! 会的可以加我 149799880 的球球!

4年前 评论

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