请简述下oAuth2.0

487 阅读5分钟

参考文档 www.ruanyifeng.com/blog/2014/0…

[TOC]

一个假想的场景

有一款云冲印应用,需要访问用户存储在 google 的图片。

没有oauth时的情况

办法

用户不得不把自己在google的用户名、密码告诉云冲印客户端。

问题

  • 云冲印客户端得到了用户在 google 资源服务器的用户名密码
  • 云冲印客户端得到了全部的访问权限
  • 万一需要收回权限,只能通过重置密码。这样又会导致其他客户端失去权限
  • 只要有一个客户端被破解,用户的用户名密码就会失窃

oauth2.0

OAuth的作用就是让"客户端"安全可控地获取"用户"的授权,与"服务商提供商"进行互动。

oauth 在 “客户端” 和 “服务提供商” 之间,设置了一个授权层。“客户端” 不能直接登录 “服务提供商”,只能登录授权层,“服务提供商” 以此将 “客户端” 和 “用户” 区分开来。“客户端” 登录授权层所用的 “令牌 token”,与 “用户” 的密码不同。“用户” 可以在授权的时候,指定授权层 token 的权限范围和有效期。 “客户端” 拿到 token 后,在访问 “服务提供商” 的时候,“服务提供商” 会根据 token 的权限范围和有效期,向 “客户端” 开放相应的资源。

涉及的几个端

5 和 6 后文貌似没有提及

  1. 云冲印客户端 【client || 第三方应用程序 || Third-party application】
  2. 用户 【user || 资源所有者 || Resource Owner】
  3. google 认证服务器 【Authorization server】
  4. google 图片资源服务器 【Resource server】
  5. Google 服务提供商 【HTTP service】
  6. 浏览器 【User Agent】

流程

前提是 google 服务提供商提供 oauth 服务。

  1. 客户端【用户已登录客户端自己的服务器】请求认证服务器,跳转到认证服务器【参数中有 response_type: code 以及 redirect_uri 等】
  2. 用户同意授权
  3. 认证服务器返回code到客户端并跳转回客户端
  4. 客户端带code请求自身服务器,自身服务器带code请求认证服务器
  5. 认证服务器校验后返回 access_token 以及 refresh_token
  6. 客户端使用 access_token 请求 google 图片资源服务器内容【客户端直接请求google资源 || 客户端请求自身服务器,自身服务器请求google资源】
  7. 如何更新令牌:客户端用之前的 refresh_token 按照规则获取新的 access_token 以及 refresh_token。

这里说的 token 和微信的 access_token 的区别

微信的 access_token 不用什么用户授权,是每个应用【公众号、app等】使用自己的 appid appsecret 等信息直接去请求微信的接口获得的,通过这个 access_token,可以使用微信的功能,比如发推送,用户分组、获取指定 unionid 的用户信息等。

掘金微信登录和 oauth 是什么关系

区别联系

  1. 微信提供了 oauth 功能

  2. oauth只是这个 “掘金微信登录” 流程的一部分。

  3. 用户微信oauth授权后,获取的微信资源较特殊。 因为掘金 app 在微信开放平台注册了应用,所以掘金使用微信oauth,就能得到用户在掘金的 appid 下在微信开放平台的unionid openid 以及微信头像、昵称等信息。目标资源就是这些信息。

  4. 得到用户 unionid 后,oauth 就完成了。

  5. 之后掘金就能从自身数据库中得到用户的信息【把微信的 unionid 和掘金用户对应起来】,之后设置cookie等常规操作就可以了。

  6. 掘金自己的登录流程完成。

掘金登录流程

掘金app 登录

  1. 在掘金app 点击微信登录
  2. 跳转到微信
  3. 微信确认
  4. 跳转回掘金app
  5. 登录成功

浏览器网页掘金登录

  1. 弹出微信二维码 open.weixin.qq.com/connect/qrc…

  2. 用户扫码确认

  3. 微信二维码页关闭,网页登录成功

一种微信登录流程

手机端 H5 登录

  1. 前端呼出微信登录模板
  2. 前端得到微信返回的 code
  3. 前端将 code 传给 node auth 服务
  4. node 使用 code 通过微信接口得到用户的微信信息,如 openid unionid 等
  5. node 带着这些信息【也许查 redis 更进一步得到用户在我们这的user_id】去请求后端 Python 服务
  6. Python 服务处理用户逻辑【包括创建新用户】,返回一个 auth 值【给 oauth 无关,跟微信无关,只是一个约定】
  7. node 将得到的信息【包括 Python 返回的 auth 】返回前端
  8. 前端拿着 auth 直接请求 Python 后端,后端确认是该用户,set-cookie,用户登录成功。

pc 端扫码登录

  1. 我们的 node 服务端请求微信生成一个包含 loginid【只是一个约定字符】 的微信二维码
  2. 用户微信扫码即相当于授权
  3. 微信服务器收到用户扫码事件,请求我们的 node 服务,带上了用户的 openid 等信息
  4. node 带着这些信息【也许查 redis 更进一步得到用户在我们这的user_id】去请求后端 Python 服务
  5. Python 服务处理用户逻辑【包括创建新用户】,返回一个 auth 值【给 oauth 无关,跟微信无关,只是一个约定】
  6. node 通过 websocket 或前端轮询告知浏览器网页该 auth 值
  7. 前端拿着 auth 直接请求 Python 后端,后端确认是该用户,set-cookie,用户登录成功。

拓展:oauth1.0 vs 1.0a vs 2.0

www.zhihu.com/question/19…