本机移动应用程序的一个常见功能是即使用户关闭相关应用程序也能保持登录状态(例如,参见iOS上的Facebook应用程序)。
对于通过用户名/密码对Rails后端进行身份验证的Cordova / Ionic / PhoneGap应用程序,如何实现这一目标?
我正在使用devise_token_auth gem来促进对Rails的身份验证,如果这有所不同的话。
本机移动应用程序的一个常见功能是即使用户关闭相关应用程序也能保持登录状态(例如,参见iOS上的Facebook应用程序)。
对于通过用户名/密码对Rails后端进行身份验证的Cordova / Ionic / PhoneGap应用程序,如何实现这一目标?
我正在使用devise_token_auth gem来促进对Rails的身份验证,如果这有所不同的话。
我最近一直在考虑这个问题,我认为我有一个有效的解决方案。我对Rails一无所知,但这个想法应该转移。我只有Mongo的数据库经验,所以请耐心等待。
每个设备都有一个唯一的标识符,可以使用device.uuid在Cordova中检索(来自Cordova插件)或getUUID()(如果你正在使用ngCordova)。此ID仅保证对于每个平台都是唯一的,尽管它可能在所有平台上都是唯一的,因此您应该将平台和模型添加到您的唯一标识符中以获得良好的衡量标准。
var deviceId = device.platform + device.model + device.uuid;
现在我们已经创建了一个永远不会改变的真正独特的ID,您不必处理本地存储。
现在假设您的数据库中有一个设备集合或表格,其中包含以下键值对。
{
device: DEVICEID;
loggedIn: true;
userId: USERID;
}
现在,当应用程序启动时,从设备中获取deviceId并将其发送到您的服务器以进行搜索。这可能与您不同,只是一个简单的键值搜索。
var result = Devices.find({device: deviceId}).fetch();
在Mongo中,这将返回一个结果数组,但应该只有一个结果。现在我们检查他们以前是否登录并抓住userId。
var loggedIn = result[0].loggedIn;
var user = result[0].userId;
如果他们之前已注销或没有结果,请将他们带到登录页面。如果他们已登录,请自动运行正常的登录过程。 用户id可以是指向另一个集合中的对象的指针。
这就是我认为我会这样做,或者你可以让用户对象将设备ID作为键,但是用户可以拥有多个设备,因此它必须是一个键组,我不知道如何现在搜索。 添加新设备就像将唯一ID添加到集合并将其指向用户一样简单。
每次应用打开时,它都会检查设备ID并查看用户是否已登录设备。发生这种情况时,您可以显示启动画面。
现在,如果用户从设置中选择退出,您可以更新数据库以反映该数据库,并且下次他们转到应用程序时,他们将被注销。
我希望我的想法可以提供帮助。
编辑: 我认为每次退出时从集合中删除设备对象可能会更好,而不是仅仅设置loggedIn,这样如果他们摆脱了设备,它将不会保留在您的集合中。我不确定删除对象通常会如何影响数据库的性能,但是就我所知,用户不会经常退出设备,所以它不应该是一个太大的问题。
这提出了另一点,使用的设备。这是一个简单的补救措施,但每次用户登录现有设备时,如果更改了userId键,则将其更新为新用户。
进一步编辑(因为我无法评论): 在本地存储/缓存以及为什么它是危险的。您可以在本地存储中自动自动登录某人的唯一方法是他们的帐户凭据,这是高度敏感的信息,不应该存储在本地(密码不应远程存储,但散列是一个单独的主题)。您永远不会将其密码存储在缓存中,您可以组成一些密钥并存储它,但本地可访问的任何内容都可以被某人读取并可能在另一台设备上复制。设备ID信息将更难伪造。
对不起,我无法评论(需要50个代表),但我认为使用localStorage是一个有效的选项。你可以创建一个 JSON Web令牌(JWT) 并将其存储在缓存中。
在Android上,除非您通过进入“设置”明确清除应用程序的缓存,否则即使您强行停止或从多任务窗格中删除,该应用程序也会让您的用户登录(即不会终止缓存)。我不确定它在iOS中是如何工作的。
我强烈推荐这个 由jmdobry设计的惊人的Cache Wrapper
此外,有惊人的第三方库可以为您处理身份验证:
我希望这有帮助!祝你好运。
不是很安全,但你可以使用Cordova / JS友好的localStorage ..
if ( logged_in_successfully ) {
localStorage.setItem("email", email)
localStorage.setItem("password", password)
}