从移动客户端做oAuth的“正确”方式

时间:2013-02-14 23:10:17

标签: node.js oauth xamarin.ios xamarin.android passport.js

我正在构建一个跨平台的移动应用程序(使用Xamarian工具,MonoTouch / MonoDroid)。我正在尝试通过身份验证工作流程,并遇到了绊脚石。我已经搜遍了一个明确的答案,但还没有找到它。

以下是我当前设置的概述。

我有一个内置nodejs的网站。 我使用passport.js在网站上进行oAuth登录。这很好用,用户可以使用Twitter或Facebook登录我的网站。

现在我想将这个相同的登录功能扩展到我的移动客户端。

我看到2个选项

  1. 将app id和app secret嵌入移动客户端,并通过移动应用程序直接向FB或Twitter发出oAuth调用

  2. 代理oAuth通过我现有的nodejs Web服务器调用(保留服务器上的密钥)

  3. 选项2似乎是首选方式(因为它避免了在移动应用程序中“发送”秘密)。

    我主要使用代理方法。

    1. 我在移动客户端中打开了一个WebView,并将其指向http://mysever/auth/twitter
    2. 这会运行我现有的passport.js代码,并将移动WebView重定向到Twitter登录页面。
    3. 然后,用户在设备的Twitter网页上输入他们的信用卡。
    4. Twitter然后调用我的oAuth回调URL(这是我的nodejs web服务器)。
    5. 我的服务器和Twitter处理获得用户配置文件信息的第四次握手(据我所知,这是这种方法的关键,我的服务器和Twitter处理握手,移动客户端没有在此过程中必须做任何事情或传递任何令牌
    6. 这是我的问题

      1. 这是困扰我的最后一步。在我的服务器上完成握手后,我在服务器上获得了所需的用户信息,需要将其发送回移动客户端应用程序

        我无法弄清楚WebView控件中的任何方式来获取响应对象并获取cookie或标头值(例如)(对于Android和iOS来说这似乎是正确的)。我不认为它是特定于平台的。我想我正试图做一些移动平台上的WebView小部件不支持的东西。这让我觉得我错过了一些明显的东西。

      2. 我唯一能想到的就是让我的网络服务器将移动客户端浏览器“重定向”到一个伪造的URL,该URL在查询字符串中包含用户信息。有点像myapp:// info?userid = 1234

        然后在移动应用程序中,我可以劫持URL加载并获取此URL并获取我需要的数据。然后,我可以存储此userinfo,关闭WebView控件并转到我的移动应用程序中的本机屏幕,并在我的nodejs服务器的任何后续REST调用中使用userinfo作为识别用户的方法。

        由于多种原因,这是大量的kludgy。其中最大的一点是,网址是通过未加密的线路发送的,并且所有数据都是纯文本的。

        必须有更好的方法将数据从网络服务器恢复到移动客户端吗?

        或者我做错了吗?

2 个答案:

答案 0 :(得分:3)

为iOS和Android实施Xamarin的oauth最直接的方法是使用Xamarin.Auth。客户端的入门文档是here。我认为它应该安全地维护所有内容,您不必担心必须使用节点服务器作为代理。

您需要提供您的应用程序ID作为通话的一部分,但我不会担心那里有太多或任何安全问题。

我知道这与你已经实施的内容相悖,但也许这可能有助于简化一些事情。

答案 1 :(得分:0)

这与我一直在处理的困境相同。 这就是我目前处理它的方式。 在我的应用程序中,客户端可以直接或通过另一项服务,例如facebook,这是我的主要服务,因此也是我专注的服务。

Facebook可以通过POST(桌面应用程序)或GET(移动)重定向。

我检查初始请求,看看是否有服务标识符 - 例如,这里是facebook GET。

app.get('/', function(req, res) {
var paraUrl = URL.parse(req.url,true).query;
//The fb_source is shown - 
//i need to go striaght to the facebook authorization since 
//its coming from
//from a mobile device.
if (paraUrl.fb_source){
res.redirect('/auth/facebook'); //this is the passport part
return;
}
res.sendfile('index.html');
}

facebook POST略有不同,因为你在base64url中获得了一个访问令牌编码。 GET为您提供了一个代码,您可以使用该代码交换访问令牌,但我遇到了问题,只是选择了绑定护照系统。

如果客户端是直接的,我会检查会话或加密的cookie,它与本地策略有关。然后,它会检查db以获取访问令牌,该令牌可用于访问facebook api。

如果客户端无法识别,他们可以选择通过Facebook,谷歌等进行身份验证。

主要的是客户端只存储了2条信息,护照会话ID和我的应用用户ID

connect.sid - encypted cookie

userId - encypted cookie

我很想知道其他人如何处理问题