OAuth 2.0支持几种grant type,由于安全性不同,所以适用范围也不同。背景知识:《理解OAuth 2.0》《OAuth 2 Simplified》

grant type 是否需要secret 是否出现授权界面
授权码模式(Authorization Code)
隐藏模式(Implicit)
密码模式(Password)
客户端证书模式(Client credentials)

secret需要保密,而常见的使用场景能否保密呢?如下:

使用场景 能否保密
web server site
web server api
web app(为避免混乱,下面称为js app) 不能
native app(Android, iOS等) 不能

可以看到app(js,Android, iOS等)无法保密,所以需要无secret的模式才行,也就是隐藏模式(Implicit)或密码模式(Password)。从安全性和可维护性角度考虑,Password模式是让用户直接输入密码,所以只提供给厂商自己app使用。第三方app只有隐藏模式(Implicit)可用,各家服务商的安全警告如下:

  • Google : Installed apps are distributed to individual machines, and it is assumed that these apps cannot keep secrets. 原文链接
  • Facebook : This app secret should never be included in client-side code or in binaries that could be decompiled. 原文链接

现在来看看常用的账号体系服务商支持的grant type。

账号体系 web支持Authorization Code web支持Implicit mobile sdk支持Implicit
Google 支持 支持js sdk支持 支持
Facebook 支持 js sdk支持 支持
Github 支持 否,无sdk
QQ 支持 支持 支持
微信 支持 支持但文档错误
微博 支持 支持,但文档没说,混乱 支持,但文档没说,混乱

可以看到Github只支持授权码模式,只能在web server上用,不支持app,请谨慎使用。不过由于github是生产力工具,使用github登录的第三方网站也都是生产力工具,比如gitbook.comtravis-ci.org,只在web上用,也是可以理解的。

而微信不支持web Implicit,所以只支持web server,不支持js app,在纯API架构下,会带来混乱。

纯API架构是只开发一套api,同时支持各种app(js、Android、iOS),而没有了web server site。架构如图(https://www.processon.com/view/link/567220ace4b0f79964befccd):

如果再使用OAuth Client即第三方登录,那它的纯API架构如下(https://www.processon.com/view/link/566fe5d1e4b0554d8cfaa6e2):

可以看到大部分公司做API仅供自家app使用,也就是私有API,用这种架构就可以了。多亏了API的HTTP server是自家的,所以也能把授权码模式加进去,用来支持github/微信,即自家js app可以和api共用app key和secret,api替它用code换token。架构如下(https://www.processon.com/view/link/56723463e4b0f79964c05229):

而如果API本身需要开放,假设叫做api.example.com,那将变成双重OAuth架构,自家app调用流程:https://www.processon.com/view/link/5672343ee4b02f55904265bf,第三方app调用流程:https://www.processon.com/view/link/567a4b76e4b06915fbfc5ff6,截图:

可以看到:

自家app使用Password模式,集成多家sdk,直接显示多家登录按钮,体验很好。如果在api里加入支持github/微信,可以做,但会把Password模式打乱,难以维护,最佳方案是:js app有自己的简单后端,自己去github换token。

第三方app使用隐藏模式,集成example家的一个sdk,跳转到example的登录页或唤起example的Android/iOS app,然后看到多家的登录按钮(google/facebook/qq/微信/github),再跳转或唤起它们……有点奇怪,但也能使用。想支持github/微信却很简单,example的授权页可以帮它换。