如何管理从本地移动应用程序调用 Play2!-Scala REST 服务发送的用户请求的身份验证/授权
Posted
技术标签:
【中文标题】如何管理从本地移动应用程序调用 Play2!-Scala REST 服务发送的用户请求的身份验证/授权【英文标题】:How to manage Authentication/Authorization for user requests sent from native mobile apps calling Play2!-Scala REST services 【发布时间】:2012-08-14 18:33:28 【问题描述】:我一直在研究 Play2!Scala 文档,了解为用户请求实现身份验证/授权的可能方法,我必须说我有点迷茫。 我想了解更多关于从移动设备发送的请求如何在 Play2!Scala 支持的 REST 服务上进行身份验证/授权的信息。
首先,Play2/scala 似乎有很多身份验证模块:例如t2v's Play20-auth。但问题是,这些解决方案基于在客户端存储 cookie。那正确吗 ?从纯网络角度来看这是有道理的:请求从浏览器发送,服务器可以将 cookie 存储在客户端等。
现在,如果我有一个本地移动应用程序(在 ios 或 android 上)并且我只是调用一个由 Play2!Scala 应用程序支持的 REST 服务,该怎么办。在这种情况下,我没有使用浏览器,因此服务器无法在客户端应用程序上存储 cookie。
我还可以使用t2v's Play20-auth 之类的模块进行授权/身份验证吗?
处理这类事情的最佳做法是什么?
任何帮助将不胜感激, 提前致谢,
【问题讨论】:
不,您所指的 Play auth 模块不能用于无状态 REST 身份验证,因为是的,它使用 cookie。我建议您查看类似的问题,例如***.com/questions/454355/…,实现您自己的问题并不难。我建议远离 OAuth,除非你是受虐狂。 【参考方案1】:好的,这是为了验证,然后登录是分开的,你可以使用自己的系统或者openID之类的东西。 问题是如何存储用户已通过身份验证。
保护您的 REST 服务的主要想法是使用在服务器端使用用户标识符签名的身份验证令牌。 它会这样:
-
用户输入 ID/密码
rest 方法会对此进行检查,如果有效,则将令牌发送回手机。您将其存储在您的应用中
每次调用 REST API 时,您都会发送用户 ID 和令牌,并检查服务器上的令牌。
您有两种生成和检查令牌的解决方案:
-
令牌基本上是用户 ID,与您自己的一些盐(无论您想要什么秘密消息)连接,然后在您的服务器上使用私钥签名。就我个人而言,我使用 HMAC-SHA256 完成了此操作(在我的 scala 代码中使用 javax.crypto)。
如果有人尝试使用您的 REST API,他们将无法生成令牌,因为他们不知道您的私钥或秘密。
每次您在 REST API (3) 上收到请求时,您只需重新计算哈希值并将其与作为令牌发送的哈希值进行比较。
另一种解决方案是在数据库中为每个用户存储一个随机数,而不是带有用户 ID 的 HMAC。这将是您的令牌。
每次收到请求时,您都会在数据库中检查该用户的秘密令牌,并查看它是否与查询中的相同。
这将创建无限令牌,因此您的用户永远不会被注销,您可以很容易地为这些解决方案添加到期日期:
如果使用 HMAC,则在您的令牌中(在签名之前)输入当前日期。例如,如果你想要一个 24 小时的会话,你可以这样做:
val format = new SimpleDateFormat("d/M/yyyy");
isoFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
val date = format.format(new Date());
val token = calculateHMAC(userID + date + secret);
对于更短/更长的时间段,您可以更改格式以包含更多或更少,以便每次生成令牌以检查它时,您都属于同一时间段。
对于随机数/数据库解决方案,您只需存储随机令牌的创建日期,然后查看是否在您喜欢的时间段内。
如果您使用来自第三方的 OpenID(或类似)标识,则必须向加载 openID 提供程序页面的用户显示 WebView,您只需确保在身份验证后重定向页面包含隐藏在某处(例如标题中)的生成令牌,您可以使用您的应用代码提取它。
这很容易自己实现,但我看到了一个 play2 插件来处理令牌身份验证: https://github.com/orefalo/play2-authenticitytoken(从未个人使用) 一个用于无状态身份验证: https://github.com/blendlabs/play20-stateless-auth
对于登录位,您不必实现它,那里有很好的模块可供使用:
https://github.com/joscha/play-authenticate https://github.com/jaliss/securesocial【讨论】:
服务器上的token过期了怎么办?应用程序应该记住用户名和密码还是应该显示登录屏幕?其他应用如何处理这个问题?以上是关于如何管理从本地移动应用程序调用 Play2!-Scala REST 服务发送的用户请求的身份验证/授权的主要内容,如果未能解决你的问题,请参考以下文章
如何在 play 2.4 中使用 CommonsMailerPlugin