如何管理从PHP中登录的用户的会话?

时间:2022-07-16 13:00:35

I'm a PHP programmer by profession. So, I don't have any idea about iOS and Android coding.

我的职业是PHP程序员。所以,我对iOS和Android代码没有任何概念。

The scenario is there is one website developed using a Social Networking PHP software titled "PHPFox".

假设有一个网站是用名为“PHPFox”的社交网络PHP软件开发的。

Now there are two similar mobile apps which exactly replicates the functionality of this website. One mobile app is in iOS and another is in Android.

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

So, I've written a set of RESTful APIs where I'm accepting the request from mobile app, parse the request, pass the request parameters to the function which does the same job for website, get the response from this function, convert it into JSON format and sent it back to mobile app. For iOS and Android app I'm using the same set of REST API files.

所以,我写了一系列的RESTful API,我从手机应用程序接受请求,解析请求,将请求参数传递给函数为网站做同样的工作,从这个函数得到的响应,将其转换成JSON格式并将其发回手机应用程序。iOS和Android应用我使用相同的REST API集文件。

When user logs in, the REST API for login gets called. Eventually the PHPFox function for authentication gets called, a security token is generated along with some other user data. With every login the different security token is generated by PHPFox. This data is set into the session. Now every time I call any of the functions through any REST API file the security token generated at the time of login is verified and only upon successful verification of token the PHPFox function gets called. This verification process is done internally by PHPFox. So no need to pass the security token explicitly or implicitly to any REST API call.

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

Till now everything works absolutely fine.

到目前为止,一切都很顺利。

My doubt starts from here. I don't know whether the session is maintained in iOS/Android app. So, if session on server i.e. PHPFox gets timed out then what will happen to the app? Will it crash? Will the user have to login again? If user kills the app on the device and again comes to the app, does he/she have to do the login process again?

我的怀疑从这里开始。我不知道会话是否在iOS/Android应用中维护。如果服务器上的会话即PHPFox超时,那么应用会发生什么?它会崩溃吗?用户是否需要再次登录?如果用户杀死了设备上的应用,再次来到应用,是否需要再次登录?

There are too many doubts in my mind. I get totally confused with these things.

我心里有太多的疑虑。我完全搞不懂这些东西。

Can someone please put more focus on the issue I'm facing? It would be really great if you could explain in detail.

谁能把更多的精力放在我所面临的问题上吗?如果你能详细解释,那就太好了。

Thanks.

谢谢。

7 个解决方案

#1


48  

REST is sessionless for its nature. You need to generate a token when user logged in. You must save this token on your mobile client. For every request, you need to attach a valid token in request header and check it at server side. If token expires, the token stored on a client is not valid. So, you need to login again because of 401 response. If token it's not correct you need to responde 400. I hope that I'm helpful for you.

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

#2


17  

Unlike web browsers, iOS and android apps cannot maintain sessions. Usually, once a user has logged in (login credentials verified from server), its login credentials are saved on client side. Then the app gets data from server using session less REST api calls. This is how mostly it is done in mobile applications.

与web浏览器不同,iOS和android应用程序不能维护会话。通常,一旦用户登录(从服务器验证登录凭证),其登录凭证将保存在客户端。然后应用程序使用会话较少的REST api调用从服务器获取数据。这是在移动应用程序中最主要的实现方式。

However, if you want the server session and mobile app go hand in hand (which i don't think is a good idea), the way is

但是,如果你想让服务器会话和移动应用手牵手(我认为这不是一个好主意),方法是。

1) When the user logs in, a security token is generated on the server side and saved on both server and client side.

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

2) The mobile app will be able to communicate with the server as long as the security token is valid.

2)只要安全令牌有效,移动app就可以与服务器进行通信。

3) When the session expires, the security token becomes invalid. Now there must be an understanding between server and client about the response when the session is expired. Now the mobile app must redirect the user to login page again. The user will login again and then communicate with the server. This should happen every time the session is expired.

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

#3


12  

If your are using Oauth 2 for athentication, here is the common setup:

如果你正在使用Oauth 2进行认证,以下是常见的设置:

  • User logs in on mobile app
  • 用户登录移动应用
  • If the credentials are ok, the server returns the access token, a refresh token and the token's lifetime
  • 如果凭据是ok的,服务器将返回访问令牌、刷新令牌和令牌的生存期
  • The mobile app stores those values + current timestamp
  • 移动应用程序存储这些值+当前时间戳
  • On the server's side, a garbage collector is configured to clear expired tokens
  • 在服务器端,垃圾收集器被配置为清除过期的令牌
  • Before making any api call, the mobile app checks if the token is about to expire (with the help of the stored values). If the token is about to expire, the app sends the refresh token which instructs the server to generate a new access token
  • 在进行任何api调用之前,移动应用程序检查令牌是否即将过期(在存储值的帮助下)。如果令牌即将过期,应用程序将发送refresh令牌,指示服务器生成新的访问令牌
  • If you want users to stay connected, the app can be configured to check the access token periodically and request a new one if it's stale
  • 如果您希望用户保持连接,可以配置该应用程序定期检查访问令牌,并在它过时时请求新的令牌

Hope this helps.

希望这个有帮助。

Cheers

干杯

#4


6  

Your server should be completely stateless, and so no session should be stored.. a REST API is effectively just a data abstraction layer with optional security (through token)

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

So you API expose an authentication service, which will respond with an Authorization token to be used on subsequent requests as a header, this token should be a 1to1 relation with each user, and Universally Unique. It should also have an expire time, at which point your server responds with appropriate error response requesting your app to refresh the token, which can be done either via a separate refresh token system, or requesting that the user logs in again to refresh the token.

因此,您的API公开了一个身份验证服务,该服务将响应一个授权令牌,用于在后续请求中作为一个头部使用,这个令牌应该是与每个用户之间的1to1关系,并具有普遍的惟一性。它还应该有一个过期时间,此时服务器响应适当的错误响应,请求应用程序刷新令牌,这可以通过单独的refresh token系统完成,也可以请求用户再次登录以刷新令牌。

It is the APP which should maintain the state, not the server. The server is merely there for data purposes, and so should not rely on any kind of session based authentication.

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

#5


4  

You should not worry about the session from the mobile development side.I don’t know much about iOS but in Android we use SharedPrefrence (Flag which maintains the session locally).

您不应该担心移动开发方面的会话。我不太了解iOS,但在Android中,我们使用SharedPrefrence(标志,在本地维护会话)。

#6


3  

I dont have any experience working with PHPFox but this is how a mobile frontend should ideally handle the issues:

我没有与PHPFox合作的经验,但这是一个移动前端应该理想地处理这些问题的方式:

Case 1: Mobile app actively talking to server:

案例1:手机app主动与服务器对话:

  • Session timeout stamp keeps bumping up and session stays alive.
  • 会话超时戳记不断增加,会话保持活跃。

Case 2: Mobile app active without any server communication (e.g. incoming phone call, moving between apps etc.):

案例二:手机app活动,没有任何服务器通信(如来电、app间移动等):

  • Server session may or may not timeout.
  • 服务器会话可能超时,也可能超时。
  • If it times out, next query to server will fail auth and return an error.
  • 如果超时,则对服务器的下一个查询将失败并返回一个错误。
  • App consumes this error and gracefully redirects to login screen with a message toast urging the user to login. (This happens in my banking app)
  • 应用程序使用这个错误,并优雅地重定向到登录屏幕,提示用户登录。(这发生在我的银行应用中)

Case 3: User kills the app on device and relaunches it:

案例3:用户在设备上杀死app并重新启动:

  • The app should store the token either in sqllite or shared preferences. (Always logged in apps take this approach)
  • 应用程序应该将令牌存储在sqllite或共享首选项中。(经常登录应用程序采用这种方法)
  • Upon relaunch, app can query the server with the presistent token.
  • 重新启动后,app可以使用主席令牌查询服务器。
  • If session is alive, communication goes through and user can continue. If not, user goes to login screen as in Case 2.
  • 如果会话是活动的,通信将通过,用户可以继续。如果没有,用户将进入登录屏幕,如案例2所示。

#7


3  

A session is "something" that lives on the server. It can be an object storing details about the user (for instance session id, username, email address...) or any other data that will be required to process future requests (such as shopping cart details, delivery address...).

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

That "something" is typically an object, which can be stored in memory, in a database or even serialized and saved to the file system (I believe this is the default in PHP).

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

So when you say "I don't know whether the session is maintained in iOS/Android app", I'm afraid that doesn't make sense. Only the server can maintain sessions.

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

Typically, the only thing that the client would know (web browser or mobile app) is the session id (in the form of a token or GUID). That is the only thing the client/app needs to remember and it needs to be sent alongside any request to the server.

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

It could be stored as a cookie and/or sent to the server as a request header.

它可以存储为cookie,或者作为请求头发送到服务器。

Then the server will read the session id/token from the cookies or header and will retrieve the session details from the place where it stores sessions (file system, memory or database). That is what happens behind the scene when you call session_start().

然后,服务器将从cookie或header中读取会话id/令牌,并从存储会话的位置(文件系统、内存或数据库)检索会话细节。这就是调用session_start()之后发生的情况。

To read more about session handling and how to create custom session handler (which might be required in your case to get a token from the request headers):
http://php.net/manual/en/function.session-start.php

要了解更多关于会话处理和如何创建自定义会话处理程序(在您的案例中,可能需要从请求头获取令牌):http://php.net/manual/en/function.session-start.php

#1


48  

REST is sessionless for its nature. You need to generate a token when user logged in. You must save this token on your mobile client. For every request, you need to attach a valid token in request header and check it at server side. If token expires, the token stored on a client is not valid. So, you need to login again because of 401 response. If token it's not correct you need to responde 400. I hope that I'm helpful for you.

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

#2


17  

Unlike web browsers, iOS and android apps cannot maintain sessions. Usually, once a user has logged in (login credentials verified from server), its login credentials are saved on client side. Then the app gets data from server using session less REST api calls. This is how mostly it is done in mobile applications.

与web浏览器不同,iOS和android应用程序不能维护会话。通常,一旦用户登录(从服务器验证登录凭证),其登录凭证将保存在客户端。然后应用程序使用会话较少的REST api调用从服务器获取数据。这是在移动应用程序中最主要的实现方式。

However, if you want the server session and mobile app go hand in hand (which i don't think is a good idea), the way is

但是,如果你想让服务器会话和移动应用手牵手(我认为这不是一个好主意),方法是。

1) When the user logs in, a security token is generated on the server side and saved on both server and client side.

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

2) The mobile app will be able to communicate with the server as long as the security token is valid.

2)只要安全令牌有效,移动app就可以与服务器进行通信。

3) When the session expires, the security token becomes invalid. Now there must be an understanding between server and client about the response when the session is expired. Now the mobile app must redirect the user to login page again. The user will login again and then communicate with the server. This should happen every time the session is expired.

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

#3


12  

If your are using Oauth 2 for athentication, here is the common setup:

如果你正在使用Oauth 2进行认证,以下是常见的设置:

  • User logs in on mobile app
  • 用户登录移动应用
  • If the credentials are ok, the server returns the access token, a refresh token and the token's lifetime
  • 如果凭据是ok的,服务器将返回访问令牌、刷新令牌和令牌的生存期
  • The mobile app stores those values + current timestamp
  • 移动应用程序存储这些值+当前时间戳
  • On the server's side, a garbage collector is configured to clear expired tokens
  • 在服务器端,垃圾收集器被配置为清除过期的令牌
  • Before making any api call, the mobile app checks if the token is about to expire (with the help of the stored values). If the token is about to expire, the app sends the refresh token which instructs the server to generate a new access token
  • 在进行任何api调用之前,移动应用程序检查令牌是否即将过期(在存储值的帮助下)。如果令牌即将过期,应用程序将发送refresh令牌,指示服务器生成新的访问令牌
  • If you want users to stay connected, the app can be configured to check the access token periodically and request a new one if it's stale
  • 如果您希望用户保持连接,可以配置该应用程序定期检查访问令牌,并在它过时时请求新的令牌

Hope this helps.

希望这个有帮助。

Cheers

干杯

#4


6  

Your server should be completely stateless, and so no session should be stored.. a REST API is effectively just a data abstraction layer with optional security (through token)

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

So you API expose an authentication service, which will respond with an Authorization token to be used on subsequent requests as a header, this token should be a 1to1 relation with each user, and Universally Unique. It should also have an expire time, at which point your server responds with appropriate error response requesting your app to refresh the token, which can be done either via a separate refresh token system, or requesting that the user logs in again to refresh the token.

因此,您的API公开了一个身份验证服务,该服务将响应一个授权令牌,用于在后续请求中作为一个头部使用,这个令牌应该是与每个用户之间的1to1关系,并具有普遍的惟一性。它还应该有一个过期时间,此时服务器响应适当的错误响应,请求应用程序刷新令牌,这可以通过单独的refresh token系统完成,也可以请求用户再次登录以刷新令牌。

It is the APP which should maintain the state, not the server. The server is merely there for data purposes, and so should not rely on any kind of session based authentication.

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

#5


4  

You should not worry about the session from the mobile development side.I don’t know much about iOS but in Android we use SharedPrefrence (Flag which maintains the session locally).

您不应该担心移动开发方面的会话。我不太了解iOS,但在Android中,我们使用SharedPrefrence(标志,在本地维护会话)。

#6


3  

I dont have any experience working with PHPFox but this is how a mobile frontend should ideally handle the issues:

我没有与PHPFox合作的经验,但这是一个移动前端应该理想地处理这些问题的方式:

Case 1: Mobile app actively talking to server:

案例1:手机app主动与服务器对话:

  • Session timeout stamp keeps bumping up and session stays alive.
  • 会话超时戳记不断增加,会话保持活跃。

Case 2: Mobile app active without any server communication (e.g. incoming phone call, moving between apps etc.):

案例二:手机app活动,没有任何服务器通信(如来电、app间移动等):

  • Server session may or may not timeout.
  • 服务器会话可能超时,也可能超时。
  • If it times out, next query to server will fail auth and return an error.
  • 如果超时,则对服务器的下一个查询将失败并返回一个错误。
  • App consumes this error and gracefully redirects to login screen with a message toast urging the user to login. (This happens in my banking app)
  • 应用程序使用这个错误,并优雅地重定向到登录屏幕,提示用户登录。(这发生在我的银行应用中)

Case 3: User kills the app on device and relaunches it:

案例3:用户在设备上杀死app并重新启动:

  • The app should store the token either in sqllite or shared preferences. (Always logged in apps take this approach)
  • 应用程序应该将令牌存储在sqllite或共享首选项中。(经常登录应用程序采用这种方法)
  • Upon relaunch, app can query the server with the presistent token.
  • 重新启动后,app可以使用主席令牌查询服务器。
  • If session is alive, communication goes through and user can continue. If not, user goes to login screen as in Case 2.
  • 如果会话是活动的,通信将通过,用户可以继续。如果没有,用户将进入登录屏幕,如案例2所示。

#7


3  

A session is "something" that lives on the server. It can be an object storing details about the user (for instance session id, username, email address...) or any other data that will be required to process future requests (such as shopping cart details, delivery address...).

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

That "something" is typically an object, which can be stored in memory, in a database or even serialized and saved to the file system (I believe this is the default in PHP).

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

So when you say "I don't know whether the session is maintained in iOS/Android app", I'm afraid that doesn't make sense. Only the server can maintain sessions.

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

Typically, the only thing that the client would know (web browser or mobile app) is the session id (in the form of a token or GUID). That is the only thing the client/app needs to remember and it needs to be sent alongside any request to the server.

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

It could be stored as a cookie and/or sent to the server as a request header.

它可以存储为cookie,或者作为请求头发送到服务器。

Then the server will read the session id/token from the cookies or header and will retrieve the session details from the place where it stores sessions (file system, memory or database). That is what happens behind the scene when you call session_start().

然后,服务器将从cookie或header中读取会话id/令牌,并从存储会话的位置(文件系统、内存或数据库)检索会话细节。这就是调用session_start()之后发生的情况。

To read more about session handling and how to create custom session handler (which might be required in your case to get a token from the request headers):
http://php.net/manual/en/function.session-start.php

要了解更多关于会话处理和如何创建自定义会话处理程序(在您的案例中,可能需要从请求头获取令牌):http://php.net/manual/en/function.session-start.php