oAuth 机制对于网站间的授权管理是很容易实现的,设置好 app 回调端口,当数据服务提供方拿到其用户授权,则返回授权码发送到回调端口。上一篇文章介绍了如何授权 Forge app 访问 Autodesk 云应用数据,即,获取三条腿的 token。
但移动端的原生 app,授权码返回到发起请求 app 的某个 Activity,可如何得知是哪个 Activity 并且跳转到此 Activity?这时就要用到 URL Scheme。iOS 和 Android 都提供了这样的机制。它实现了页面内跳转协议,通过定义自己的 scheme 协议,非常方便跳转到 app 中的各个 Activity。也让不同 app 可以唤起其它 app 的 Activity。当然,前提 app 已经安装到系统。这位大咖对此话题做了专业的讲解,推荐大家先阅读:https://www.jianshu.com/p/7b0…
我的同事 Bryan 搭建了一个框架,演示 Android app 集成 Forge oAuth,拿到三条腿 token,并调用了用户信息(Profile)API,列出登录用户的在 Forge 数据管理中的基本信息。该框架很好的展示了使用 URL Scheme 整个过程。https://github.com/dukedhx/oa…
我借此学习了有关内容。另外,基于此代码,略微改造,添加流程展示获取 Autodesk 云应用的 Hub,Project,Folder 和 File,为进一步的综合应用 app 做一些铺垫。https://github.com/xiaodongli…
oAuth 相关的几个步骤:
1. 定义监听 oAuth 回传的 Activity 属性
<activity android:name=”.MainActivity”>
<intent-filter>
<action android:name=”android.intent.action.MAIN”/>
<category android:name=”android.intent.category.LAUNCHER”/>
</intent-filter>
<intent-filter>
<data android:scheme=”@string/FORGE_CALLBACK_SCHEME” android:host=”@string/FORGE_CALLBACK_HOST”/>
<action android:name=”android.intent.action.VIEW”/>
<category android:name=”android.intent.category.DEFAULT”/>
<category android:name=”android.intent.category.BROWSABLE”/>
</intent-filter>
</activity>
其中,FORGE_CALLBACK_SCHEME 和 FORGE_CALLBACK_HOST 定义为:
<string name=”FORGE_CALLBACK_SCHEME”>lxdapp</string>
<string name=”FORGE_CALLBACK_HOST”>mytest3legged</string>
同样的, URL Scheme 必须和 Forge app 注册的时候填写的 callback URL 要一致。
2. 登录事件将创建一个 Intent.ACTION_VIEW,用以启动网页,URL 拼接了 Forge app 的 client id,授权方式(response_type=code),回传地址和授权的权限范围 跳转到 Autodesk 登录过程,等待客户授权。
public void onLoginClick(View v) {
Intent i = new Intent(Intent.ACTION_VIEW);
Resources resources = getResources();
i.setData(Uri.parse(getResources().getString(R.string.FORGE_AUTHORIZATION_URL) + “?response_type=code&redirect_uri=” + this.getCallbackUrl() + “&scope=” + resources.getString(R.string.FORGE_SCOPE) + “&client_id=” + resources.getString(R.string.FORGE_CLIENT_ID)));
startActivity(i);
}
3. 用户授权后,将对 URLScheme 地址回传,也就是发起请求的 Activity。Activity 的 OnStart 拿到回传信息。由于没有设定 android:mimetype, 则任何数据类型都可接收。但我们需要只是授权码,在回传请求的 URL 参数中。
@Override
protected void onStart() {
super.onStart();
Intent intent = getIntent();
Uri data = intent == null ? null : intent.getData();
// 从回传请求中拿到授权码
String authorizationCode = data == null ? null : data.getQueryParameter(“code”);
if (authorizationCode != null && !authorizationCode.isEmpty()) {
……
4. 接下来的过程就和常规的网页应用类似了,依授权码得到最终的 token。
5. 该样例调用 Forge 服务采取 okhttp3, 推荐参考下文的详细讲解:https://www.jianshu.com/p/da4…
注:
Activity 的 URLScheme 是可能同名的,而且如何保证应用之间跳转和传参的目标正确性,这方面我还在研究中。
本例为方便计,将 Forge Client Secret 也存在了 app 之中。我想安全的方式是由 app 服务器端进行 secret 的管理,当原生 app 拿到授权码,通过它来向 app 服务器端发起请求,由 app 服务器来获取 Forge token,再传回原生 app。
扩展的部分(Hub,Project,Folder 和 File)只是简单的替换 ListView 的内容,尚未对页面回退做处理。