如何在 PHP 中管理从移动应用程序登录的用户的会话?

Posted

技术标签:

【中文标题】如何在 PHP 中管理从移动应用程序登录的用户的会话?【英文标题】:How to manage session for a user logged in from mobile app in PHP? 【发布时间】:2015-04-23 05:34:50 【问题描述】:

我的职业是PHP 程序员。所以,我对 iosandroid 编码一无所知。

场景是有一个网站使用名为“PHPFox”的社交网络php软件开发。

现在有两个类似的移动应用程序完全复制了该网站的功能。一个移动应用在 iOS 中,另一个在 Android 中。

所以,我编写了一组 RESTful API,我在其中接受来自移动应用程序的请求,解析请求,将请求参数传递给对网站执行相同工作的函数,从该函数获取响应,将其转换为 JSON 格式并发送回移动应用程序。对于 iOS 和 Android 应用,我使用的是同一组 REST API 文件。

当用户登录时,用于登录的 REST API 被调用。最终,用于身份验证的 PHPFox 函数被调用,安全令牌与其他一些用户数据一起生成。每次登录时,PHPFox 都会生成不同的安全令牌。该数据被设置到会话中。现在,每次我通过任何 REST API 文件调用任何函数时,都会验证登录时生成的安全令牌,并且只有在成功验证令牌后才会调用 PHPFox 函数。此验证过程由 PHPFox 在内部完成。因此无需将安全令牌显式或隐式传递给任何 REST API 调用。

到目前为止一切正常。

我的疑惑从这里开始。我不知道会话是否在 iOS/Android 应用程序中维护。那么,如果服务器上的会话,即 PHPFox 超时,那么应用程序会发生什么?它会崩溃吗?用户是否必须再次登录?如果用户在设备上杀死该应用程序并再次访问该应用程序,他/她是否必须再次执行登录过程?

我心中有太多的疑惑。我对这些事情完全感到困惑。

有人可以更关注我面临的问题吗?如果你能详细解释一下,那就太好了。

谢谢。

【问题讨论】:

那么最后你是如何维护会话的,请回复我遇到了同样的问题?? 【参考方案1】:

与网络浏览器不同,iOS 和 android 应用程序无法维护会话。通常,一旦用户登录(从服务器验证登录凭据),其登录凭据就会保存在客户端。然后应用程序使用无会话 REST api 调用从服务器获取数据。这就是它在移动应用程序中的主要完成方式。

但是,如果您希望服务器会话和移动应用程序齐头并进(我认为这不是一个好主意),那么方法是

1) 用户登录时,服务器端会生成一个安全令牌,并保存在服务器端和客户端。

2) 只要​​安全令牌有效,移动应用就可以与服务器通信。

3) 当会话到期时,安全令牌失效。现在,服务器和客户端之间必须了解会话过期时的响应。现在移动应用程序必须再次将用户重定向到登录页面。用户将再次登录,然后与服务器通信。每次会话过期时都会发生这种情况。

【讨论】:

感谢您的回答,但我认为您没有完全理解我的观点。当用户通过 iOS/Android 应用程序从设备登录时,服务器上的会话开始,PHPFox 生成设置到此会话中的安全令牌。在应用程序的每个后续请求中,PHPFox 都会在内部验证此安全令牌以保护功能。我的疑问是,如果用户没有从应用程序中注销并且服务器上的会话超时,即 PHPFox 会话被关闭,那么我该怎么办?为此,我认为会话也需要在应用端维护。 并且来自应用程序的会话应该与来自服务器的会话同步。只有这样,问题才不会提出。简而言之,我认为这两个会议应该齐头并进。我说的对吗?【参考方案2】:

如果您使用 Oauth 2 进行身份验证,以下是常用设置:

用户在移动应用上登录 如果凭据正常,则服务器返回访问令牌、刷新令牌和令牌的生命周期 移动应用存储这些值 + 当前时间戳 在服务器端,垃圾收集器配置为清除过期令牌 在进行任何 api 调用之前,移动应用程序会检查令牌是否即将过期(借助存储的值)。如果令牌即将过期,应用程序会发送刷新令牌,指示服务器生成新的访问令牌 如果您希望用户保持连接状态,可以将应用配置为定期检查访问令牌,并在过期时请求新的访问令牌

希望这会有所帮助。

干杯

【讨论】:

如果有人可以窃取您的令牌,那么刷新令牌有什么用,那么他/她也可以窃取您的刷新令牌?? @amanverma 刷新令牌可以被撤销。这些通常与无法手动撤销的自编码令牌 (JWT) 等短期访问令牌配对。【参考方案3】:

我没有任何使用 PHPFox 的经验,但这是移动前端理想地处理问题的方式:

案例 1:移动应用主动与服务器对话:

会话超时标记不断增加,会话保持活动状态。

案例 2:移动应用程序在没有任何服务器通信的情况下处于活动状态(例如来电、在应用程序之间移动等):

服务器会话可能会也可能不会超时。 如果超时,对服务器的下一个查询将失败并返回错误。 应用程序使用此错误并优雅地重定向到登录屏幕,并带有一条消息 toast 敦促用户登录。 (这发生在我的银行应用中)

案例 3:用户杀死设备上的应用并重新启动它:

应用程序应将令牌存储在 sqllite 或共享首选项中。 (始终登录的应用采用这种方法) 重新启动后,应用可以使用永久令牌查询服务器。 如果会话处于活动状态,则通信通过并且用户可以 继续。如果没有,用户会像案例 2 一样进入登录屏幕。

【讨论】:

【参考方案4】:

REST 本质上是无会话的。您需要在用户登录时生成一个令牌。您必须将此令牌保存在您的移动客户端上。 对于每个请求,您需要在请求标头中附加一个有效的令牌并在服务器端进行检查。 如果令牌过期,则存储在客户端上的令牌无效。因此,由于 401 响应,您需要再次登录。如果令牌不正确,则需要响应 400。 希望对你有帮助。

【讨论】:

您描述的令牌听起来与会话 ID 完全相同。 是的,但请告诉我一件事,您可以检查大多数 Android 应用程序,他们不再要求登录,现在他们没有设置任何到期时间还是他们做了什么?? 也许他们可以开发一个系统来了解令牌是否过期,然后将令牌返回给其应用程序。或者令牌永不过期。我建议您阅读有关 oauth 的内容。 这就是使用代币的美妙之处!与会话不同,它们永远不会隐式过期,除非明确杀死它们。 这是真的!但是,令牌将在一段时间后过期是一种很好的做法。 JSON Web Token 才是王道!【参考方案5】:

您不必担心来自移动开发方面的会话。在 Android 中,我们使用 SharedPrefrenceNSUserDefaults(在本地维护会话的标志)。

【讨论】:

非常适合安卓! iOS 中的 NSUserDefaults【参考方案6】:

您的服务器应该是完全无状态的,因此不应存储任何会话。REST API 实际上只是一个具有可选安全性(通过令牌)的数据抽象层

因此,您的 API 公开了一个身份验证服务,该服务将使用授权令牌作为标头进行响应,该授权令牌将在后续请求中使用,该令牌应该是与每个用户的 1to1 关系,并且是通用唯一的。它还应该有一个过期时间,此时您的服务器会以适当的错误响应进行响应,请求您的应用程序刷新令牌,这可以通过单独的刷新令牌系统完成,或者请求用户再次登录以刷新令牌.

应该维护状态的是APP,而不是服务器。服务器仅用于数据目的,因此不应依赖任何类型的基于会话的身份验证。

【讨论】:

这种方法的缺点是如果服务器不存储令牌,它就不能使令牌过期。 当然服务器正在存储令牌,服务器需要存储令牌以对客户端进行身份验证......但这就是它的全部存储,它不应该存储任何其他会话详细信息。跨度> 对不起,我以为你的意思是完全无状态的,比如 JWT 身份验证。但是你的意思是保持客户端在数据库中拥有什么令牌的状态,而不是通过传统会话。【参考方案7】:

会话是存在于服务器上的“东西”。它可以是一个对象,存储有关用户的详细信息(例如会话 ID、用户名、电子邮件地址...)或处理未来请求所需的任何其他数据(例如购物车详细信息、送货地址...)。

“某物”通常是一个对象,可以存储在内存中、数据库中,甚至可以序列化并保存到文件系统中(我相信这是 PHP 中的默认设置)。

所以当你说“我不知道会话是否在 iOS/Android 应用程序中维护”时,恐怕这没有意义。只有服务器可以维护会话。

通常,客户端(Web 浏览器或移动应用程序)唯一知道的是会话 ID(以令牌或 GUID 的形式)。这是客户端/应用程序唯一需要记住的事情,它需要与任何请求一起发送到服务器。

它可以存储为 cookie 和/或作为请求标头发送到服务器。

然后,服务器将从 cookie 或标头中读取会话 ID/令牌,并从存储会话的位置(文件系统、内存或数据库)检索会话详细信息。当您致电session_start() 时,这就是幕后发生的事情。

要了解有关会话处理以及如何创建自定义会话处理程序(在您的情况下可能需要从请求标头获取令牌)的更多信息:http://php.net/manual/en/function.session-start.php

【讨论】:

以上是关于如何在 PHP 中管理从移动应用程序登录的用户的会话?的主要内容,如果未能解决你的问题,请参考以下文章

如何在移动设备的重定向页面上传递 PHP 会话值?

当应用程序在本地运行时如何修复 PHP 上的重定向错误

如何在多个 apache 服务器上管理单个 PHP5 会话?

PHP学习笔记:使用session来存储用户的登录信息

在 PHP 中按用户删除帖子/条目

web应用中实现同一个账号,后面登录的会把前面登录的挤下线