`

OAuth2疑问解答

阅读更多
OAuth2的学习,我也是从阮一峰老师的博客中开始的:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html
下文中以“该博客”指代阮老师的博客。

但,阮一峰老师的博客似乎忽略了很多细节。

OAuth2的实际应用中,最常见的就是“授权码模式”了。
微博是这种模式,微信也是这种模式。
总结来说,就是简单的二步:
1.获取code
2.根据code,去获取access_token



以微博为例(http://open.weibo.com/wiki/%E6%8E%88%E6%9D%83%E6%9C%BA%E5%88%B6%E8%AF%B4%E6%98%8E):

假设我们开发一个网站(称为client;相对应的,微博就是server了),网站允许用户以微博账号登录,且需要读取用户的微博信息(账号、评论等等)。
显然,这过程中需要用户授权。

第一步:
https://api.weibo.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&response_type=code&redirect_uri=YOUR_REGISTERED_REDIRECT_URI

第二步:
https://api.weibo.com/oauth2/access_token?client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&grant_type=authorization_code&redirect_uri=YOUR_REGISTERED_REDIRECT_URI&code=CODE


这其中有几个问题:
1.获取code时,传递的二个变量(clent_id,redirect_url),没有一个是跟用户有关的,那微博怎么知道我们请求的是哪个用户的授权呢?
这个问题现在看来很可笑,但刚开始确实是蒙圈了。
其实,在第一步的URI发出后,是要求用户跳转到server端登录的。这很好理解,如果用户不登录,那你怎么知道是哪个用户呢,他又怎么给你授权呢?
此外,可以看到,第一步的URI,放在我们网站页面的任何位置都可以;它也不要求传递跟session相关的任何信息。
这个URI对应的页面是微博开发的,跟我们网站没关系。
事实上,这个URI可以直接拷贝到浏览器里发起请求;这个时候,是浏览器跟微博的一个交互,我们的网站是一无所知的。
那什么时候我们得知用户给我们授权了呢?
第一步URI的请求,浏览器得到的是一个http的重定向响应,这个重定向指向的就是我们的网站;此时浏览器向我们的网站发起请求:
类似于:
https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz
站在我们网站后台程序的角度来看,我们是“忽然”(在此这前,它一无所知)收到一个code了,而这个code,是跟微博的一个用户一一对应的,我们拿这个code向微博发起请求,就能获得用户的授权,获得access_token,再发起另一请求,就可以获取用户信息了。

2.为什么在第一个URI请求发出后,微博的302重定向响应中,没有直接返回access_token,而是只返回一个code呢?
其实最初我的疑问更可笑:我想,为什么微博不直接返回access_token给我们网站呢?
这个问题的答案是,发起第一步的URI请求的,是浏览器!还记得前面我说的“我们的网站是一无所知”吗?此时微博是与浏览器在通信,而不是我们的网站,当然不能把参数传返回到我们网站了。
微博只能通过返回一个302响应,让浏览器重新向我们网站发起请求,把code传到我们网站来。

回到第二个问题。
该博客下有人是这样回答的:

为什么授权码模式需要这个授权码 当然是为了安全性 首先在OAuth体系中access_token是作为访问获取资源的唯一凭据 如果在AS授权完成之后 直接通过重定向传回access_token 那么HTTP 302不是安全的 Attacker有可能会获取到access_token 但是如果只返回Authorization code 就算别人获得了也没什么卵用 因为Authorization code不能获取到资源 在client向AS请求access_token的过程中 是通过HTTPS来保证安全的 而且获得access_token是需要client secret与Authorization code一起的 Attacker知道了Authorization code但并不知道client secret 同样也不能获得到access_token 所以client与AS是有责任保护好client secret的
获得了access_token之后 向RS发起请求 RS其实会与AS交互 来校验access_token 所以你想直接伪造一个access_token 那也是不ok的


突然想到漏说了一块 关于为什么不直接用HTTPS重定向回client
是因为不是所有client server都支持HTTPS~所以为了通用性 和安全性 才衍生出来这么一个Auth code
但是AS肯定是实现HTTPS的 所以在client向AS提起request 是木有问题的~


我自己的理解,是这样的:
直接返回access_token有可能被黑客拦截到,而拿到access_token就可以获得用户信息了,非常不安全。
那最容易想到的是,微博通过https返回access_token啊,https会对access_token加密,那不就可以了吗?
为什么这个方法不可行呢?
因为有可能我们的网站不支持https!站在微博的角度来看,千千万万的第三方网站,你要求每个网站都支持https,是不太现实的。
stackoverflow上的一个回答(http://stackoverflow.com/questions/13387698/why-is-there-an-authorization-code-flow-in-oauth2-when-implicit-flow-works-s)说这是“一个巨大的痛苦”:“a huge pain”。

那为什么返回code再去获取access_token就安全了呢?
因为这时候再去获取access_token,就是https请求了,发起方为我们的网站,接收方为微博,而微博作为OAuth server,肯定提供https。
但是,另一个问题来了,黑客拿到了code,它也向微博发起请求去获取access_token是不是就可以了呢?
也是不可以的。
因为向微博请求access_token时,还要带上我们网站的“密码”(client secret)。
这个密码,是我们网站在微博开放平台上注册时获得的(同时会得到一个client_id,这个值在第一步的URI里用到了)。
这一点在该博客没有提出来,最容易让人困惑。

3.为什么简化模式(implicit grant type)是可行的?
这个在stackoverflow有回答,前面也提到过:
http://stackoverflow.com/questions/13387698/why-is-there-an-authorization-code-flow-in-oauth2-when-implicit-flow-works-s

这就涉及到一个知识点:
浏览器不会把URL当中的“hash fragment”发给服务器。hash fragment是只留在浏览器的地址栏的,它可以被网页的js读取到:window.location.hash。
既然hash fragment没有发给服务器,那即使黑客拦截到请求,也获取不到它。
什么是hash fragment?就是URL当中#号后面的那一部分。
博客中的示例:

HTTP/1.1 302 Found
Location: http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA&state=xyz&token_type=example&expires_in=3600


可以得知,“#access_token=2YotnFZFEjr1zCsicMWpAA”这一部分是留在浏览器这边的。
当浏览器接收到到该响应时,向http://example.com/cb发起请求,而后者的响应页面当中,应当有读取hash fragment的代码。
这样,client就拿到了access_token了。

解决了这三个问题,我本想到实际场景中抓包看看的,但遗憾的是,不管是蘑菇街还是聚美优品,这些允许以微博账号登录的网站,都只看到获取code那一步,没有看到获取access_token那一步。
或许改天有空可以自己在微博开放平台上注册一个应用来验证一下。
不过网上有人验证过微博的:
https://segmentfault.com/a/1190000000666685

此外还有一些关于微信OAuth2的实际例子:
http://www.cnblogs.com/txw1958/p/weixin71-oauth20.html
http://zeusjava.com/2015/04/22/wechat-get-userinfo/
都讲得比较详细。




2
5
分享到:
评论

相关推荐

    Java版水果管理系统源码-gravitee:go语言实现的轻量级oauth2服务器

    基于学员的上述反馈和疑问,同时考虑到OAuth2是微服务架构的重要环节,我决定带领大家分析一个轻量级OAuth2服务器(项目名Gravitee)的设计和实现,让大家深入理解OAuth2服务的原理和实现,同时解答大家的一些疑问。...

    病患互助平台.zip

    - **专家咨询**:可能有医生或专业人员在线解答疑问,提供医疗建议。 - **资源分享**:包括医疗文献、康复指南、心理支持资料等。 - **互助小组**:根据疾病类型创建小组,方便相似病患交流。 - **隐私保护**:...

    2020毕业设计:毕业设计选题系统.zip

    5. 互动交流模块:提供讨论区或私信功能,方便师生之间的沟通,解答学生关于课题的疑问。 6. 进度管理模块:记录每个学生毕业设计的进度,便于教师跟踪指导和评估。 7. 成果展示模块:学生完成设计后,可以上传...

    ASP.NET程序设计基础篇

    2. **在线教程**:各种在线教育平台和社区论坛(如Stack Overflow)提供了大量的学习资源和解答疑问的地方。 通过深入学习和实践这些知识点,初学者可以逐步掌握ASP.NET的基本原理和技能,为后续的Web开发打下坚实...

    微信小程序医院预约挂号小程序设计与实现.docx

    3. 在线客服:设置在线客服功能,解答用户疑问,提供即时帮助。 五、系统测试与维护 1. 功能测试:确保每个功能模块的正常运行,无逻辑错误。 2. 性能测试:模拟高并发场景,检查系统的稳定性和负载能力。 3. ...

    淘宝API开发手册.rar

    同时,官方社区论坛可以解答开发过程中的疑问,促进开发者之间的交流。 六、最佳实践 1. 尽量减少不必要的API调用,避免对淘宝服务器造成过大压力。 2. 定期更新API,遵循淘宝开放平台的更新策略,保持应用的兼容性...

    农产品交易系统

    售后服务也是关键,系统应提供退换货服务,并设置在线咨询功能,解答用户的疑问和处理投诉。此外,评价系统鼓励用户对购买的农产品进行评价,这不仅可以为其他用户提供参考,也有助于卖家提升产品质量和服务水平。 ...

    spinnaker-2018-01-24.zip

    社区的贡献者和使用者会分享实践经验,解答疑问。 综上所述,"spinnaker-2018-01-24.zip"可能包含的资源可能包括源代码、文档、示例配置等,帮助用户理解和使用2018年初的Spinnaker版本。如果你正在寻求部署和管理...

    java学习网站的设计与实现开题报告.doc

    6. **教师管理**:支持教师发布课程、管理学生、解答疑问等功能。 7. **数据安全**:确保用户数据的安全,遵循相关隐私政策。 在实现方案上,可以采用以下技术栈: - **前端技术**:使用HTML5、CSS3和JavaScript...

    C# 自动打包目录并发送邮件

    代码中提到的QQ联系信息可能是为了提供技术支持或解答用户疑问,对于开源项目来说,这种社区支持是常见的。 总的来说,这个项目展示了如何结合C#的文件操作和网络通信能力,实现自动化打包和邮件发送功能。开发者...

    基于php的考研互助交流平台.zip

    它可能包含论坛、问答、资源共享等核心功能,帮助用户分享考研经验,解答彼此的疑问,共同进步。 【描述解析】 描述中的".zip"表明这是一个压缩文件,包含了该考研互助交流平台的所有源代码和相关资源。由于没有...

    小米开发文档

    在开发过程中,如果遇到任何问题或有疑问,开发者可以随时联系小米开放平台的技术支持邮箱(developer@xiaomi.com),获得专业帮助和解答。 总的来说,小米开发文档是一个综合性的资源库,为开发者提供了从开发、...

    毕业设计商城管理系统

    7. 客服系统:提供在线客服功能,解答用户疑问,处理售后问题。 8. 数据统计:对销售数据、用户行为等进行统计分析,为决策提供依据。 四、开发过程 1. 需求分析:明确系统目标,收集并整理用户需求,绘制ER图,...

    计算机专业课程设计 网上答疑系统

    2. **问题发布**: 学生可以提出疑问,包括问题描述、标签分类,教师和其他学生可以查看并关注。 3. **回答与评论**: 教师和学生可以针对问题提供解答,支持富文本编辑,允许添加图片、代码片段等。评论功能则提供...

    postman-9.13.0-linux-x64.tar.gz

    - Postman论坛:社区用户交流平台,解答疑问和分享经验。 综上,"postman-9.13.0-linux-x64.tar.gz"是Postman为Linux用户提供的一个版本,包含了一整套API开发和测试的工具,无论是单独使用还是集成到开发流程中,...

    java租房网站源码(springboot+vue+mysql+说明文档+LW).zip

    Spring Security或OAuth2可以用于权限管理和认证,确保用户数据的安全。此外,个人中心模块可能包括订单管理、收藏房源、查看历史记录等个性化服务。 房屋类型和房屋信息管理涉及后台的 CRUD(创建、读取、更新、...

    oTraining在线培训系统.7z

    oTraining系统包含论坛或聊天室功能,促进学生之间的互动交流,教师也能参与其中解答疑问。这有助于形成良好的学习氛围,增强学习动力。 八、安全与性能 系统安全至关重要,需考虑防止SQL注入、XSS攻击等安全威胁。...

    ZuoZuoTravel.zip

    4. 客服信息:提供在线客服聊天功能,可能使用WebSocket技术实现即时通讯,同时设有常见问题解答,便于用户快速解决疑问。 总结,ZuoZuoTravel的开发涉及了Android开发的多个方面,包括UI设计、网络通信、数据存储...

    用户中心程序

    - 服务支持:提供在线客服、帮助中心,解答用户疑问。 3. 技术实现: - 前端技术:通常使用HTML5、CSS3和JavaScript进行界面设计和交互实现,框架如React、Vue或Angular可以提高开发效率。 - 后端技术:常用的...

    毕业设计选题系统

    5. **交流互动**:提供师生之间的沟通渠道,允许在线讨论,解答疑问,促进课题的顺利进行。 6. **资料上传与下载**:支持相关文献、参考材料的上传,学生可下载学习,教师也可查看学生提交的作业和进度报告。 7. *...

Global site tag (gtag.js) - Google Analytics