Skip to content
王伟兵 edited this page Feb 6, 2017 · 7 revisions

github OAuth实现不支持implicit grant type,仅支持标准的authorization code grant type
测试sandstorm.io与github的OAuth授权是任何实现的。github的OAuth授权参考这个文档

访问[sandstorm.io],首页上有登录按钮(假定已经注册过sandstorm的用户)。点击登录按钮,屏幕提示的登录方式中有“github login”的按钮。点击按钮后,发出的请求如下:

https://github.com/login/oauth/authorize?client_id=e70ac36adf3f539b6f73&scope=user%3Aemail&redirect_uri=https://oasis.sandstorm.io/_oauth/github&state=eyJsb2dpblN0eWxlIjoicmVkaXJlY3QiLCJjcmVkZW50aWFsVG9rZW4iOiJrSUQ1Z25NaXZKUF91VGU0YmMxRnJNVGRwa3hsbDV5dkNoTXFLa2tONEYtIiwiaXNDb3Jkb3ZhIjpmYWxzZSwicmVkaXJlY3RVcmwiOiJodHRwczovL29hc2lzLnNhbmRzdG9ybS5pby8ifQ==

state是个不可猜测的随机数,用来防止CSRF攻击。client_id是sandstorm向github申请的。下面会申请自己的clientid,参考“注册应用”一节。这个请求的其他参数可参考这个

sandstorm向github发出上述请求,github可能会弹出的页面有:

  • 弹出登录页面(如果用户还没有登录github)
  • 弹出授权页面(如果用户已经登录github,但没有授权过sandstorm) 如果用户已经登录github并且授权过sandstorm相应的scope权限,则会返回302响应:
Location:https://oasis.sandstorm.io/_oauth/github?code=5228a92e166798116623&state=eyJsb2dpblN0eWxlIjoicmVkaXJlY3QiLCJjcmVkZW50aWFsVG9rZW4iOiJrSUQ1Z25NaXZKUF91VGU0YmMxRnJNVGRwa3hsbDV5dkNoTXFLa2tONEYtIiwiaXNDb3Jkb3ZhIjpmYWxzZSwicmVkaXJlY3RVcmwiOiJodHRwczovL29hc2lzLnNhbmRzdG9ybS5pby8ifQ%3D%3D

相比之前的redirect_uri多出了一个code。这个code是个临时码,用来换取真正OAuth访问令牌(access token)。 按照github OAuth授权的官方文档说明,换取访问令牌的请求是:

POST https://github.com/login/oauth/access_token

必须的参数有client_id,client_secret,code。由于要发送client_secret,导致这个请求只能由应用后台发出。没法访问sandstorm后台,所以就无法知道sandstorm是否发出了换取访问令牌的请求。
换取访问令牌的响应是:

access_token=e72e16c7e42f292c6912e7710c838347ae178b4a&scope=user%2Cgist&token_type=bearer

访问令牌的两种使用方式:

$ curl -H "Authorization: token OAUTH-TOKEN" https://api.github.com
$ curl https://api.github.com/?access_token=OAUTH-TOKEN

注册应用和获取token

登录github后,访问这个链接可以注册应用。也可以在登录github后,在屏幕右上角的头像下菜单中通过连续点击settings/OAuth Applications/Register a new application来注册应用。

注册过程中输入的callback URL是http://webdav.imaicloud.com。注册应用后可以得到Client ID和Client Secret:

Client ID
671ee08a3de5bf9e93bb
Client Secret
0e9ca641c834756221b987c157833b3f*****9ba

仿照前面sandstorm.io构造自己的请求:

https://github.com/login/oauth/authorize?client_id=671ee08a3de5bf9e93bb&scope=delete_repo&redirect_uri=http://webdav.imaicloud.com&state=3333

把上面的请求粘贴到浏览器地址栏,回车后如果从来没有授权过,会弹出授权页面,点击Authorize application按钮。浏览器被重定向到:

http://webdav.imaicloud.com/?code=3589f9056eafa0822c31&state=3333

上面的code就是授权码。如果之前授权过,会直接重定向到上面的地址。 需要注意的是scope参数,这指定了授权范围。关于scope的详细说明参考这个文档。请求中的scope=delete_repo表示想获得删除代码库的权限,没有这个权限,下面的删除代码库的API请求将无法执行。

用授权码(code)换access token,需要构造一个URL:

https://github.com/login/oauth/access_token?client_id=671ee08a3de5bf9e93bb&client_secret=0e9ca641c834756221b987c157833b3f*****9ba&code=3589f9056eafa0822c31

把上述URL粘贴到浏览器中回车,会自动下载一个叫access_token的文本文件,里面就是token:

access_token=5b8010f9058e6a4cf6348661d9f8cc0c*****e0e&scope=delete_repo&token_type=bearer

利用token测试github API

首先利用基础认证的方式创建一个叫nameOfRepo的库:

$ curl -u wbwangk:$PASSWD -X POST https://api.github.com/user/repos -d '{"name":"nameOfRepo"}'

也可以利用gihhub的界面创建这个nameOfRepo的库。 利用上面取得的token删除刚才创建的库:

$ export GITHUB_TOKEN=5b8010f9058e6a4cf6348661d9f8cc0c*****e0e
$ curl -H "Authorization: token $GITHUB_TOKEN" -X DELETE https://api.github.com/repos/wbwangk/nameOfRepo