Closed TakWolf closed 8 years ago
服务器需要增加啥? 我改一版服务器方便你测试。我搭了一个copy在我的服务器上。http://bbs.zuqiuxunlian.com
别折腾这块,没意义。。。就扫码登陆。
2016-05-16 20:05 GMT+08:00 Ten Wong notifications@github.com:
服务器需要增加啥? 我改一版服务器方便你测试。我搭了一个copy在我的服务器上。bbs.zuqiuxunlian.com
— You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub https://github.com/TakWolf/CNode-Material-Design/issues/37#issuecomment-219409776
@alsotang LOL 给点鼓励啊。 如果有时间,可以整一下顺便学习一下。 500px上用facebook登录有相似之处。
@awong1900 @alsotang
没事研究,只是想表明这个在客户端上是可以实现的。
这个就是标准的Auth授权流程,没有啥复杂的原理,过程也简单明了。
另外,通过抓取页面解析出accessToken,这根本就不是正常的手段!!这是hack!!就算真的实现了这个代码,也不会放到线上环境中。
@TakWolf 恩。 尝试直接用chrome等第三方浏览器打开,然后重定向到app,就不用hack了。
@awong1900
在Chrome中授权之后打开APP吗? 是Android还是iOS? 给一个链接研究一下
android 和 ios都可以。安装DO Button by IFTTT, 然后有个channel绑定,然后选择github服务。最好翻墙。我用BlueStacks测试。
还有一个亮点是,如果绑定的服务也是第三方登录,也可以继续用第三方登录。这个可以参考trello的channel服务
@awong1900 研究了一下Android,方式是一样的都是Auth2.0,流程都是一样的,授权动作跳转到了浏览器。 最后一步回调成功之后,浏览器返回App用的是私有协议。Android的参考:http://developer.android.com/training/app-indexing/deep-linking.html
用浏览器不用WebView的原因是验证授权重定向全由服务器搞定了,客户端可以省不少事
@TakWolf
以上是否可行?
@awong1900 实现方式可以有很多种,这里只研究do button它的流程。
反编译do button,在manifest中发现这个配置:
<activity android:name="com.ifttt.dobutton.LinkActivity" android:theme="@style/Theme.IFTTT.Lib">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="dobutton"/> // 私有协议
</intent-filter>
</activity>
Android打开媒体的Action,如果只有一个接收方式,则会直接调用,如果有两个以上,则会竞争,由用户选择。于是,我们创建一个新的项目,注册一个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>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="dobutton" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="https" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="http" />
</intent-filter>
</activity>
这样就会跟浏览器类型以及dobutton的私有类型产生竞争,然后我们在oncreate中监听url,就可以跟踪do button具体打开链接了:
public class MainActivity extends AppCompatActivity {
protected WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = (WebView) findViewById(R.id.webview);
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Log.d("ttaa", url);
return false;
}
});
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.removeAllCookie();
String url = getIntent().getDataString();
if (!TextUtils.isEmpty(url)) {
Log.d("ttaa", url);
webView.loadUrl(url);
}
}
}
首先,绑定channel动作(GitHub),由do button打开浏览器,url如下:
https://ifttt.com/channels/github/activate?activation_failure_path=dobutton://url//appviews/channels/2107379463/activate_fail?access_token=xxxxxxxxxxxxxxxx&app_version=2.1&bundle_id=com.ifttt.dobutton&mobile_app_id=&sdk_mode=&system_version=&use_for_profile=false&activation_success_path=dobutton://url//appviews/channels/2107379463/activate_done?access_token=xxxxxxxxxxxxxxxx&app_version=2.1&bundle_id=com.ifttt.dobutton&mobile_app_id=&sdk_mode=&system_version=&use_for_profile=false&is_web_view=1&user_id=123456&expires=1463458515&token=yyyyyyyyyyyyyyyyyyyyy
这个链接是指向ifttt.com的,参数包含用户token,因此对用户进行了鉴权操作,之后,重定向路线:
https://ifttt.com/channel_activation/github/start
https://ifttt.com/channel_activation/github/approve
https://shimmy.ifttt.com/github/oauth2/authorize?client_id=ifttt_production&redirect_uri=https://ifttt.com/channels/github/authorize&response_type=code&scope=ifttt&state=zzzzzzzzzzzzzzzzzzzzzzzzzzzz
// 从这里开始,就是正常的Auth2流程了:
https://github.com/login/oauth/authorize?scope=user,repo,notification,gist&client_id=8eebda59593bc42170e4&response_type=code&redirect_uri=https://ifttt.com/channels/github/authorize&state=zzzzzzzzzzzzzzzzzzzzzzzzzzzz
// 由于我没登录,跳转到github登录
https://github.com/login?return_to=someurl
Auth2.0授权成功之后,url线路图(略去Auth2.0中的部分,只看关键的步骤):
// 这个是Auth2成功回调地址:
https://ifttt.com/channels/github/authorize?code=qqqqqqqqqqqqqqqq&state=zzzzzzzzzzzzzzzzzzzzzzzzzzzz
https://ifttt.com/channels/github/activate_success
// 这一步是关键,使用私有协议打开APP
dobutton://url//appviews/channels/2107379463/activate_done?access_token=xxxxxxxxxxxxxxxx&app_version=2.1&bundle_id=com.ifttt.dobutton&mobile_app_id=&sdk_mode=&system_version=&use_for_profile=false
这里的access_token是最开始的access_token,用户比对一致后鉴权完成,APP开始刷新数据,整个授权完成。
---------------------------- 分隔符 -------------------------------------
实现方式有很多种,原理都是一样的,其实没必要纠结于do button是怎么完成的,自己选择合适的实现方式就可以。
do button的这种模式:
补充一句:我更倾向于使用WebView来完成这个动作,因为chrome浏览器是标准实现,如果你在国内rom上使用,授权链接转到了国产浏览器或者类似QQ内置浏览器就完蛋了,他根本不会给你回调。
在WebView中,你只要拦截私有协议,然后做动作就行,功能上和chrome完全一样,但是更安全。
// 这一步是关键,使用私有协议打开APP dobutton://url//appviews/channels/2107379463/activate_done?access_token=xxxxxxxxxxxxxxxx&app_version=2.1&bundle_id=com.ifttt.dobutton&mobile_app_id=&sdk_mode=&system_version=&use_for_profile=false
这个链接是谁发出来的?
所以说https://github.com/login/oauth/authorize 这条API不是直接通过app发出来,而是服务器location过来的?
私有协议是浏览器发出了。 浏览器通常可以支持扩展协议,比如迅雷协议:thunder://xxxx Android支持这个特性
dobutton的授权链接是由服务器重定向来的,这样做的原因猜测:
那现在梳理回来,如果cnode实现github登录,需要app和服务器端分别修改什么呢?
如果不用hack,CNode官方API支持Auth登录,两种方式:
问题来源于:https://cnodejs.org/topic/57345764c3e4ef7657ab127b
研究了一下,基本可行,思路如下:
初始化一个WebView,载入CNode登录地址:https://cnodejs.org/auth/github
这句会重定向到:https://github.com/login/oauth/authorize?response_type=code&redirect_uri=http://cnodejs.org/auth/github/callback&client_id=0625d398dd9166a196e9
这是简单模式的Auth2.0,clientId是公开的且没有客户端认证
GitHub登录成功后,携带token回调: https://cnodejs.org/auth/github/callback?code=xxxxxxx
CNode验证成功后,会重定向到首页:https://cnodejs.org/
这时截断这个重定向,取出CNode的session_cookie,用这个session_cookie去抓取设置页面:https://cnodejs.org/setting
解析Dom文档,取出accessToken:
补充:这个只是研究,只为证明Auth登录在客户端可以做,实际不会真正实现到线上环境中。
Auth本身就是为客户端设计的一种授权模式,而web端使用的Auth登录,通常是一种简化版的Auth,移除了签名以及客户端认证,添加了回调来响应通知。(浏览器看成是一种特殊的客户端)
CNode的API没有提供Auth的验证接口,所以抓取页面解析accessToken的做法只是一个hack,不是一个正常的方式!!
正常的方式是,API中提供一个接口,用authToken换 accessToken
补充2:闲着无聊,还是把这个实现了,233
项目地址在:https://github.com/TakWolf/CNode-OAuth-Login-Android
实现节点为:https://github.com/TakWolf/CNode-Material-Design/commit/48e4bb346f7ffc85d582b0ad295196666b8de05b