参考文档 www.ruanyifeng.com/blog/2014/0…
[TOC]
一个假想的场景
有一款云冲印应用,需要访问用户存储在 google 的图片。
没有oauth时的情况
办法
用户不得不把自己在google的用户名、密码告诉云冲印客户端。
问题
- 云冲印客户端得到了用户在 google 资源服务器的用户名密码
- 云冲印客户端得到了全部的访问权限
- 万一需要收回权限,只能通过重置密码。这样又会导致其他客户端失去权限
- 只要有一个客户端被破解,用户的用户名密码就会失窃
oauth2.0
OAuth的作用就是让"客户端"安全可控地获取"用户"的授权,与"服务商提供商"进行互动。
oauth 在 “客户端” 和 “服务提供商” 之间,设置了一个授权层。“客户端” 不能直接登录 “服务提供商”,只能登录授权层,“服务提供商” 以此将 “客户端” 和 “用户” 区分开来。“客户端” 登录授权层所用的 “令牌 token”,与 “用户” 的密码不同。“用户” 可以在授权的时候,指定授权层 token 的权限范围和有效期。 “客户端” 拿到 token 后,在访问 “服务提供商” 的时候,“服务提供商” 会根据 token 的权限范围和有效期,向 “客户端” 开放相应的资源。
涉及的几个端
5 和 6 后文貌似没有提及
- 云冲印客户端 【client || 第三方应用程序 || Third-party application】
- 用户 【user || 资源所有者 || Resource Owner】
- google 认证服务器 【Authorization server】
- google 图片资源服务器 【Resource server】
- Google 服务提供商 【HTTP service】
- 浏览器 【User Agent】
流程
前提是 google 服务提供商提供 oauth 服务。
- 客户端【用户已登录客户端自己的服务器】请求认证服务器,跳转到认证服务器【参数中有 response_type: code 以及 redirect_uri 等】
- 用户同意授权
- 认证服务器返回code到客户端并跳转回客户端
- 客户端带code请求自身服务器,自身服务器带code请求认证服务器
- 认证服务器校验后返回 access_token 以及 refresh_token
- 客户端使用 access_token 请求 google 图片资源服务器内容【客户端直接请求google资源 || 客户端请求自身服务器,自身服务器请求google资源】
- 如何更新令牌:客户端用之前的 refresh_token 按照规则获取新的 access_token 以及 refresh_token。
这里说的 token 和微信的 access_token 的区别
微信的 access_token 不用什么用户授权,是每个应用【公众号、app等】使用自己的 appid appsecret 等信息直接去请求微信的接口获得的,通过这个 access_token,可以使用微信的功能,比如发推送,用户分组、获取指定 unionid 的用户信息等。
掘金微信登录和 oauth 是什么关系
区别联系
-
微信提供了 oauth 功能
-
oauth只是这个 “掘金微信登录” 流程的一部分。
-
用户微信oauth授权后,获取的微信资源较特殊。 因为掘金 app 在微信开放平台注册了应用,所以掘金使用微信oauth,就能得到用户在掘金的 appid 下在微信开放平台的unionid openid 以及微信头像、昵称等信息。目标资源就是这些信息。
-
得到用户 unionid 后,oauth 就完成了。
-
之后掘金就能从自身数据库中得到用户的信息【把微信的 unionid 和掘金用户对应起来】,之后设置cookie等常规操作就可以了。
-
掘金自己的登录流程完成。
掘金登录流程
掘金app 登录
- 在掘金app 点击微信登录
- 跳转到微信
- 微信确认
- 跳转回掘金app
- 登录成功
浏览器网页掘金登录
-
弹出微信二维码 open.weixin.qq.com/connect/qrc…
-
用户扫码确认
-
微信二维码页关闭,网页登录成功
一种微信登录流程
手机端 H5 登录
- 前端呼出微信登录模板
- 前端得到微信返回的 code
- 前端将 code 传给 node auth 服务
- node 使用 code 通过微信接口得到用户的微信信息,如 openid unionid 等
- node 带着这些信息【也许查 redis 更进一步得到用户在我们这的user_id】去请求后端 Python 服务
- Python 服务处理用户逻辑【包括创建新用户】,返回一个 auth 值【给 oauth 无关,跟微信无关,只是一个约定】
- node 将得到的信息【包括 Python 返回的 auth 】返回前端
- 前端拿着 auth 直接请求 Python 后端,后端确认是该用户,set-cookie,用户登录成功。
pc 端扫码登录
- 我们的 node 服务端请求微信生成一个包含 loginid【只是一个约定字符】 的微信二维码
- 用户微信扫码即相当于授权
- 微信服务器收到用户扫码事件,请求我们的 node 服务,带上了用户的 openid 等信息
- node 带着这些信息【也许查 redis 更进一步得到用户在我们这的user_id】去请求后端 Python 服务
- Python 服务处理用户逻辑【包括创建新用户】,返回一个 auth 值【给 oauth 无关,跟微信无关,只是一个约定】
- node 通过 websocket 或前端轮询告知浏览器网页该 auth 值
- 前端拿着 auth 直接请求 Python 后端,后端确认是该用户,set-cookie,用户登录成功。