记接口当中使用 session 是如何被排斥的
第一次在 Laravel
的接口当中使用 Session
,受到成吨的伤害。
话不多说,直奔主题吧。
使用的代码是刚通过 composer create-project --prefer-dist laravel/laravel blog
安装的。
首先先来调用下 Session
,路由为 api.php
中的接口路由,并在首页 welcome.blade.php
中使用 JQuery
的 $.get()
来访问下该接口。
访问下看是否设置成功。
这样应该是设置成功了吧,再加点判断,看下客户端能不能找到 Session
。
看下结果。
What ?为啥没找到我的我名字呢?通过读文档知道还有另一种写法,我们再来尝试下看看。
再看下结果。
Emmmm...直接报错了,有点过分了吧。直接 Google
报错信息发现,Laravel
中的 Session
被封装了,要使用 Session
必需要开启 Session
中间件。而默认 api
中没有开启该中间件,如下图所示。
大家有没有在 web
中看到 \Illuminate\Session\Middleware\StartSession::class
这个中间件,从字面意思应该很清楚了吧?这个就是开启 Session
的中间件,让我们加在下面的 api
中再尝试下。
没报错了,但是好像还是获取不到上一次请求设置的 Session
啊,灰常尴尬。让我们从客户端获取服务端 Session
的原理开始思考,大家应该都知道,Session
在设置时,会伴随 Cookie
在客户端的生成,当客户端请求时会带上设置好的 Cookie
,一般存的是 session_id
,服务端拿到这个 session_id
后就能顺利拿到 Session
。那我们能设置只是找不到,会不会是 Cookie
出错了呢?所以让我们看看接口响应的 Cookie
。(PS:我设置了 .env
中的 SESSION_LIFETIME
为24小时,这里就不多赘述了,并且为了区别,我设置了 APP_NAME
为 test
以区分 Laravel
自己生成的 Cookie
)
这里主要看是否有 Value
和 Expires
,都有值且过期时间为1天,不存在秒过期的情况。那是为什么呢?
各位,请仔细看 Request
中的 Cookie
与响应 Response
的 Cookie
,有没有发现 Value
有很明显的差别,完全不像是一个应用生成的 Cookie
,并且当你刷新页面时原本 Request
中的 test_session
应该替换为上一次请求中的 Response
中的 test_session
,这样就能找到之前设置好的 Session
了,但实际是又重新生成了一个不同的 Cookie
。那么问题很明显了,设置 Session
返回的 Cookie
是有误的,导致框架每次加载时,判断这个 Cookie
为无效的并重新生成了一个新的,所以找不到之前的 Session
。
让我们又回到中间件那里。
我在 web
中又发现一个 \App\Http\Middleware\EncryptCookies::class
,字面意思,一个 Cookie
加密中间件。好像跟我们的问题有关系诶,我已经将它添加到 api
中,我们再试一下。
哎哟,终于好了,接口里面使用 Session
就这样被排斥吗 :cry:
本作品采用《CC 协议》,转载必须注明作者和本文链接
api不应该使用session。。
@JeffLi 我只是单纯的在论述这么一个问题,不是说一定要在接口中使用session。而且单纯做 web 的接口使用 session 也是可以的,更何况 session_id 也同样能作为 token
@JeffLi 能否说下原因呢.这个问题也困扰了我很久...为何....
@韩槑槑 嗯 ,我看得出来
@落伽 因为接口作用之一就是提供给多端使用,而除了 web 端之外的都不使用 session,比如 App
@落伽 博主说的是恰当的,web中自然是可以使用session,如果在app的api 中qui使用session.... 反正我做了两年多是没用过这种操作,准确的原因我也不清楚,只是一个约定俗成的习惯,都是用token
@JeffLi 我文章里面有说到,服务端之所以能找到 session,是因为在生成 session 的时候同时在客户端生成了相应的 cookie,浏览器会在下次请求时在请求头中带上 cookie,这样就能找到 session,而 app 不会自己带上 cookie,也就不能找到 session 了。除非你每次请求时手动带上 sessionid 或 cookie。但是与其这样还不如直接用 token。
session
需要在请求头里面带session_id
这个参数要确定当前请求对应的 session , 然后API请求是无状态的, 所以, 我们在API里面不能, 注意不是不应该, 而是不能 使用session(虽然通过某些方法可以使用)@韩槑槑 :ok_hand: 感谢指导!
@韩槑槑 我看有大佬说session是基于cookie的?
@JeffLi 是的,在基本的session原理是基于cookie的,因为cookie存的就是session_id。当你不想用 cookie 时,可以手动在请求中加上 session_id。别谈论这个了,我只是单纯的说出发现的这么一个问题。?
@韩槑槑 顺带了解一下冷知识 嘿嘿嘿
对于你这个需求,直接把 api 路由放 web.php 里面即可,而不是 api.php
@leo 我正在尝试,也想了好多办法,就是不行。跟楼主正好相反,他是api路由去获取session。我是使用curl发送到指定的api路由里,这个方法里进行存储session 信息。但是当刷新网站时,就没有了。api:session、cookie都加了,甚至设置了session.php 文件中的 .***.com 跨域问题。始终没有实现!请指教啊。头疼了一天了!
curl 到laravel 的api或web, 进入方法后无法存入session ,有大佬知道什么原因吗? api 也加入了session 着急想解决这个问题,可以红包! 会的可以加我 149799880 的球球!