SSO:用户一次登陆后在多个系统免登录。
博客gem 'doorkeeper' https://i.cnblogs.com/EditPosts.aspx?postid=9255973
OAuth:用户授权第三方应用访问自己的资源无需提供账号密码。
1. 维基百科:
OAuth(开放授权)是一个开放标准,允许用户让第三方应用(网站/app)访问该用户在另一网站(qq, 微博,微信等等)上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。
OAuth允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth让用户可以授权第三方网站访问他们存储在另外服务提供者的某些特定信息,而非所有内容。
2 流程图(用git账号登陆第三方网站)
简单易学的PPT:(作者大?)
https://ruby-china.org/topics/15825
(笔记和摘录)
目标
- OAuth2 协议怎么运行的
- 看懂基于OAuth2的第三方API
- 知道怎么用Oauth2 锁你的API(不理解)
课表
- Oauth2是什么
- 通信协定怎么跑
- 制造Oauth2 Provider的方法(没看, 幻灯片224页)
- 第一次用rails+ grape api整合oauth2 就上手(略, 244页)
OAuth2.0: the OAuth2.0 authorization framework
Oauth2是什么:
Resource
Resource Owner = User的情况
- 就是你的网站上的User
- API拉到的是根User有关的资料
- 比如好友名单,信件内容
- 授权必须由本人亲自确认
Resource Owner = Client
- 爬公开的资料,没有个体人的存在
- Twitter称为App-Only Authorization
- Facebook称为App Access Token
Client
- User授权给第三方程序,这个程序就是Client (我的理解:web网站服务器)
- 例子:手机上的APP, Facebook上的游戏, 桌面app。
Client必须事先注册
- “Client Registration”
- Client ID
- Client secret (密码)
- Redirect URl (重要?)
在Facebook上注册获得facebook_app_id, facebook_app_secret, 在facebook上设置redirect URIs
Redirect URI
- User本人确认使用Facebook登陆后,返回结果到Client。
- 要事先指定URl, 若不一致,则不可Redirect过去
- 可以指定多组,上面的图指定了2组。
- 推荐使用HTTPS.
Public 对比 Confidential Client
- 根据【能否保护资料】来区分:
- Confidential-Server-Side application 机密的服务器端程序
- Public-手机app/桌面程序/Javascript App/ Browser Extension
Client Authorization(使用于Confidential Client)
-
- 出示Client ID + Secret 向 Auth.Server认证自己(我是一个服务器商业机构,我想获得user的信息)
- Client要登入到Auth.Server(Facebook的开发者相关的服务器)
Client
-
- 有ID/Secret用于登陆
- 用Redirect URI确认 浏览啊转地址到 正确的Client.
- Public/Confidential 这2种模式有各自的授权流程(token获得流程)
Endpoints(可见下面的图)
3个端点:
- Authorization Endpoint(授权端): 用来给User本人确认授权
- Token Endpoint: 用来让Client(如:商业网站)得到Token
- Redirection Endpoint: Client用来收取资料的URls
Authorization Endpoint
- 给用户User本人一个用于授权的网页,可以填写账号名,密码。
- Client拿到Grant授权状,不是token。
- Resource Owner/User答复之后, 验证服务器(facebook)会把批准码grant传回到Redirect URI
Redirection Endpoint
- 用来从browser接收Auth.Server来的资料。
- 把资料存在Client上(猜测:这里是商业网站服务器上)
- Client在facebook上注册时,填写Redirection URL就是callback URL
Token Endpoint
- 给Client取得真正的Token
- JSON API 机械化界面,无网页。
Resource Server
- Client必须出示Token才能拿资料
- 可以使用Scope限制Token的取用范围。
- Password-Free API
- Login via Your Website
Parameters 和 Data
Client ID/Secret
- 用于Client认证(Client 登入到Auth.Server)
- HTTP Basic Auth或包在Form里面。(禁用URL)
Id和secret被base64()生成乱码,放入请求头中:
Basic Auth Header
Authorization: Basic xxx乱码
Token(s)
- Access Token: 打Api用的
- Refresh Token: Access Token过期可以换新的
Access Token:
-
- 向Resource Server要资料(user信息)
- 可以绑定一组Scope
- 可以设定气息,可以撤销Revoke
- 授权流程的目标就是拿到Access Token
Refresh Token
-
- 换发Access Token用,只会传到Auth.Server
- 和一个Access Token绑定,随Access Token一切核发
- 用过就失效,新的Access Token会绑定新的Refresh Token
Scopes
- 用来表示哪行资料可以存取的权限范围。
- 如: 好友名单, 相片, friends_list, photos
- 申请授权时可以规定它。
State
- 用来放在CSRF攻击(cross site request forgery)
- Rails使用了校验token防止了这种攻击。
怎么运行的:如果取得授权(从client视角,程序程序开发者视角)
- Client 向Res.Owner取得Grant
- Client 用Grant向Authorization Server换Token
- Token拿到,去打API
常见的scenario:
有网站Facebook, 你希望在那上面的User(Resource Owner),
透过Facebook的Authorization Server,
给你的网站(Client)权限(Token),可以读取那User的资料(Resource Server)
例子:使用你网站的user无需注册,而是使用Fackbook/qq的账号注册。
Authorization Code Grant Flow:
- Grant是具体string, 称为Code
- 需要经过Browser
- 适用Client:商业网站 。
具体过程见幻灯片(40多张)
https://speakerdeck.com/chitsaou/jian-dan-yi-dong-de-oauth-2-dot-0?slide=73
步骤A之前,已经在Facebook上注册了。
当网站上的用户点击login with Facebook按钮的时候:
(A)发出Get request:
猜测:还应该包括用户输入facebook的账号和密码。这样facebook才能找到对应用户的Res.Owner
(B)的过程,在浏览器上弹出对话框问,是否授权,用户选择同意。进入(C)
(C) 的过程,Authorization Server传回Client数据:Grant Code。
如果(B)不授权,(c)Client收到错误的信息。
Redirection endPoint会检查state和存的数据是否一致。没问题就去换Token了。
(D)步骤:
-
这是服务器后台的事情。
- 发出 POST request到Auth.Server的Token Endpoint换Token
(E)步骤:
Authorization Server:
- 确认Client Auth(Id/Secret)正确。
- 找到Grant Code, 并确认Redirect URI 相同
- 发Token
Client的Token Request的Response 是 JSON Response
可以一并发Refresh Token
手机app/桌面app因为,客户端验证不可信,所以另有一套implicit grant flow。
具体见108页的幻灯片。
自产自用的,Resource Owner Password Credentials Grant Flow
具体见148页的幻灯片。
注意:需要Resource Owner高度信赖Client。可以做系统内建的应用或官方应用程序。
不需要User, 只存取公开资料, Client Credentials Grant Flow 160页
拿到Token了,如何打API
(RFC6750 'Bearer token usage') . https://tools.ietf.org/html/rfc6750
- 出示Token给Resource Server。
- Token内容乱码就行。
- 推荐放在header中。
Token过期,换掉。 Token Refresh(217页)
制造OAuth2 Provider的方法 =造Authorization Server (没看)
第一次用rails+ grape api整合oauth2 就上手(244页, 有详细步骤)
- 用Devise生成User(Resource Owner)
- 用Doorkeeper盖 Authorization Server
- 用Grape盖API (Resource Server)
- 自己刻 Resource Server Guard 来锁api
第2步骤:
rails g doorkeeper:install
rails g doorkeeper:migration
rails db:migrate
生成3个new tables
- oauth_application: 用于Clients 注册
- oauth_access_grant: 用于储存Auth Grant Codes
- oauth_access_token: 真正核发出去的Access Tokens,包含对应的Refresh Token
routes.rb
Doorkeeper 内建的4个部分:
- Authorization Endpoint 和 Token Endpoint
- Token Debug Endpoint (在implicit flow验证token的真实性)
- Client Registration Interface(crud)
- User管理授权过的Clients的界面(可Revoke)
作者最后表示完全弄懂的话,必须看HTML官方文档。