在arkid中新建应用

参考:https://www.yuque.com/longguikeji/arkid/wg29gv

接口详情

上一步完成之后,点击应用的接口详情,后续有用的参数如下

  • 应用ID(client_id
  • 应用秘钥( client_secret
  • 重定向端点(redirect_uris
  • 认证地址(https://server.example.com/oauth/authorize/
  • 获取token地址(https://server.example.com/oauth/token/
  • 身份信息地址(https://server.example.com/oauth/userinfo/

image.png

四种授权方式

参数列表

参数 描述
reponse_type 表示请求返回的类型,有code和token两种,code表示请求返回授权码,token表示请求返回accessToken
client_id 客户端注册的时候认证服务器发放的id,用于认证客户端的身份
client_secret 客户端注册的时候认证服务器发放的客户端秘钥,用于认证客户端的身份
state 不是必须的,客户端请求认证服务器时候带上一个state,认证服务器返回的时候原封不动地返回这个state,告诉客户端是认证服务器的response,而不是别人,用于防止跨站请求攻击好像。
redirect_uri 用户授权或者否定授权以后认证服务器重定向回客户端的url
scope 表示请求的权限范围,read,write,read+write
code 授权码,用于客户端向认证服务器请求token,一般10分钟过期,而且只能使用一次
grant_type 表示授权方式, authorization_code 表示授权码方式,implicit 表示隐式, password表示密码方式, client_credentials表示凭证方式

授权码

基于授权码code,是最严谨,最安全,流程最完整的授权模式

  • 0) arkid中添加应用,记下redirect_uris,并在接口详情里查看client_idclient_secret

image.png
image.png

  • 1)用户访问客户端(第三方应用),客户端引导(重定向)用户的代理(浏览器)去到授权服务器的授权页面,这个时候客户端会在URI上附上 client_id, redirect_uri, scope以及 state.

    这里以浏览器测试为例: ```shell

    使用上一步中的 client_id和redirect_uri; state随意写,保证下边的请求一致就行.

修改后,复制粘贴到浏览器地址栏访问

https://arkid.demo.longguikeji.com/oauth/authorize/?response_type=code&client_id=1WjEWQbvsuIEmalCczq5ID3QeJV3qPdsujZ7yB2G&state=xyz&redirect_uri=http://localhost/callback/&scope=read

  1. - 2)授权服务器要求用户A输入用户密码认证身份,并询问用户A是否同意授权
  2. 点击**Authorize**<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/12498678/1616384381533-894adc5e-f3f8-4a2f-b6f0-adb5af21ba04.png#align=left&display=inline&height=392&margin=%5Bobject%20Object%5D&name=image.png&originHeight=784&originWidth=1982&size=121761&status=done&style=none&width=991)
  3. - 3)用户同意授权,授权服务器使用 redirectUri (在authorization requestredirect_uri或者客户端注册是的redirectUri)将用户导向客户端,并附上一个授权码code
  4. 不用在意报错,因为我们本地现在并没有应用。<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/12498678/1616385727244-cb7f1441-b08b-4b42-b241-0184754c8d59.png#align=left&display=inline&height=372&margin=%5Bobject%20Object%5D&name=image.png&originHeight=744&originWidth=1602&size=72716&status=done&style=none&width=801)
  5. - 4)客户端拿到授权码code以后,在后台使用授权码向授权服务器发送post请求换取accessToken令牌,并附上在(1)这个步骤请求授权码的时候的redirect_uri
  6. 这里使用postman模拟请求:<br /> Authorization使用 Basic Auth client_id client_cecret<br /> Body 也填上所需的信息<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/12498678/1616385774709-2e9b015b-c8da-4663-9da9-02a9696ac9a9.png#align=left&display=inline&height=686&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1372&originWidth=2596&size=243072&status=done&style=none&width=1298)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/12498678/1616385827891-d1e6527f-397c-4fe0-826f-53f85e7f691c.png#align=left&display=inline&height=691&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1382&originWidth=1884&size=205393&status=done&style=none&width=942)
  7. - 5)认证服务器认证客户端,检验授权码以及redirectUri,检验成功后发放 accesToken 以及 refreshToken<br />最后客户端就可以使用令牌向**身份信息地址**请求身份信息了。
  8. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/1554709/1611657113968-ba4b4eef-7951-4f3e-9908-fcfb2656c738.png#align=left&display=inline&height=350&margin=%5Bobject%20Object%5D&name=image.png&originHeight=700&originWidth=1920&size=107372&status=done&style=none&width=960)
  9. <a name="MrLKp"></a>
  10. ## 隐式
  11. 授权码模式的简化版本,缺少了授权码环节<br />有些 Web 应用是纯前端应用,没有后端。这时就不能用上面的方式了,必须将令牌储存在前端。<br />OAuth2 允许直接向前端颁发令牌。这种方式没有授权码这个中间步骤,所以称为(授权码)“隐藏式”(implicit)<br />令牌直接存储到前端浏览器,是不太安全的。
  12. - A)用户访问客户端(第三方应用),客户端引导(重定向)用户的代理(浏览器)去到授权服务器的授权页面,这个时候客户端会在URI上附上 client_id, redirect_uri, scope以及 state,例如:

GET HTTP/1.1 http://server.example.com/oauth/authorize/?response_type=code&client_id=s6BhdRkqt3&state=xyz&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb&scope=read

  1. - B)授权服务器要求用户A输入用户密码认证身份,并询问用户A是否同意授权
  2. - C)假设用户同意授权,授权服务器使用 redirectUri (在authorization requestredirectUri或者客户端注册是的redirectUri)将用户导向客户端,并附上令牌 accessToken

https://localhost/callback?#access_token=2YotnFZFEjr1zCsicMWpAA&state=xyz&token_type=example&expires_in=3600

  1. 令牌的位置URL 锚点(fragment),而不是查询字符串,好像是为了避免中间人攻击啥的 http
  2. - DEG)看网上说是使用一段脚本能够将token从(C)重定向的URI抽取出来,具体怎么时候就不是很清楚了
  3. 最后客户端就可以使用令牌向**身份信息地址**请求身份信息了。
  4. <a name="zNfaO"></a>
  5. ## 密码
  6. 第三方应用直接使用资源拥有者的用户密码去获取令牌<br />OAuth2 允许用户把用户名和密码直接告诉该应用,该应用就使用你的密码申请令牌,这种方式称为"密码式"password),直接提供账号密码,风险很大,所以应当是用户高度信任客户端才会使用这种方式。<br />客户端直接使用用户的账户密码去换取accessToken,发送的post请求:

POST http://server.example.com/oauth/token/ body: grant_type=password&username=user001&password=DasFdf234&client_id=xxx

  1. <a name="PrPmO"></a>
  2. ## 客户端
  3. 第三方应用使用客户端凭证请求令牌<br />客户端直接使用客户端凭证(client credentials)向认证服务器请求令牌,适用于没有前端的命令行应用。<br />同样使用post请求:

POST http://server.example.com/oauth/token/ body: grant_type=client_credentials&client_id=xxx&client_secret=SECRET&scope=read ```

image.png


RefreshToken

client请求token的时候,服务器会返回一个refreshToken,accessToken的过期时间很短,当accessToken过期了之后,授权服务器允许client通过refreshToken去再次请求一个新的accessToken。所以refreshToken的过期时间肯定是要比accessToken长。
refreshToken是可选的,如果对于安全要求比较高的话,可以不用。

开发示例

https://github.com/reddit-archive/reddit/wiki/OAuth2-Python-Example