OAuth 认证流程详解

作者: 耗子吴 | 来源:发表于2015-09-05 11:14 被阅读13134次

    很多网站、APP 弱化甚至没有搭建自己的账号体系,而是直接使用社会化登录的方式,这样不仅免去了用户注册账号的麻烦、还可以获取用户的好友关系来增强自身的社交功能。

    比如我们可以使用微博登录简书,简书会自动将你的微博头像设置为你的简书头像,将你的微博昵称设置为你的简书昵称,甚至还可以获取你微博中的好友列表,提示你哪些朋友已经在使用简书,这是如何做到的呢?

    最传统的办法是让用户直接在简书的登录页面输微博的账号和密码,简书通过用户的账号和密码去微博那里获取用户数据,但这样做有很多严重的缺点:

    1. 简书需要明文保存用户的微博账号和密码,这样很不安全。
    2. 简书拥有了获取用户在微博所有的权限,包括删除好友、给好友发私信、更改密码、注销账号等危险操作。
    3. 用户只有修改密码,才能收回赋予简书的权限。但是这样做会使得其他所有获得用户授权的第三方应用程序全部失效。
    4. 只要有一个第三方应用程序被破解,就会导致用户密码泄漏,以及所有使用微博登录的网站的数据泄漏。

    为了解决以上的问题,OAuth 协议应运而生。

    原理概要

    新浪微博作为服务提供商,拥有用户的头像、昵称、邮箱、好友以及所有的微博内容,简书希望获取用户存储在微博的头像和昵称,假设它们是三个人:

    1. 简书问新浪微博:我想要获取用户 A 的头像和昵称,请你提供
    2. 微博说:我需要经过用户A 本人的许可,然后去问用户 A 是否要授权简书访问自己的头像和昵称
    3. 用户 A 对微博说:我给简书一个临时的钥匙,如果他给你出示了这把钥匙,你就把我的资料给他
    4. 简书使用户给它的钥匙获取用户头像和昵称信息。

    以上是 OAuth 认证的大概流程。在使用微博授权之前,简书需要先在微博开放平台上注册应用,填写自己的名称、logo、用途等信息,微博开放平台颁发给简书一个应用 ID 和叫 APP Secret 的密钥,在实际对接中,会使用到这两个参数。

    详细流程

    接下来分步详细解释上图中每步都做了什么:

    1. 用户点击简书上的微博登录按钮,跳转到微博授权页面。微博登录按钮的链接形如下方的 URL:

        https://api.weibo.com/oauth2/authorize?client_id=123050457758183&redirect_uri=http://jianshu.com/callback
      

    URL 中要包含以下参数:
    * client_id:在微博开放平台申请的应用 ID
    * redirect_uri:授权成功后要跳转到的地址

    点击以上链接后跳转到微博的授权页面如下图:

    简书的第三方授权页面

    这个页面会告诉用户第三方应用要获取用户的哪些数据,以及拥有什么权限,比如在上图中简书会要求获得个人信息、好友关系、分享内容到微博以及获得评论的权限,用户点击“允许”则表示允许简书获得这些数据,进行下一步

    1. 页面自动跳转到初始参数中redirect_uri 定义的那个URL,并自动在 URL 末尾添加一个 code 参数,实际跳转的地址形如:

       http://jianshu.com/callback?code=2559200ecd7ea433f067a2cf67d6ce6c
      
    2. 第三步,简书通过上一步获取的 code 参数换取 Token,Token 就是前文中说到的钥匙。简书请求如下的接口获取 Token:
      POST https://api.weibo.com/oauth2/access_token
      要包含以下参数:

      • client_id:在微博开放平台申请的应用 ID
      • client_secret:在微博开放平台申请时提供的APP Secret
      • grant_type:需要填写authorization_code
      • code:上一步获得的 code
      • redirect_uri:回调地址,需要与注册应用里的回调地址以及第一步的 redirect_uri 参数一致
    3. 通过第三步的请求,接口返回 Token 和相关数据:

      {
       "access_token": "ACCESS_TOKEN",//Token 的值
       "expires_in": 1234,//过期时间
       "uid":"12341234"//当前授权用户的UID。
      }
      
    4. 在第四步中获取了access_token ,使用它,就可以去获取用户的资源了,要获取用户昵称和头像,请求如下接口:
      GET https://api.weibo.com/2/users/show.json

      携带参数:

      • access_token:上一步获取的access_token
      • uid:用户的账号 id,上一步的接口有返回
    5. 最后一步,微博返回用户信息,简书进行处理,整个流程结束。

    通过以上的方式,在简书和新浪微博中间建立了一个独立的权限层,这个权限由用户赋予,可以被用户随时取消,不同第三方应用之间相互独立,互不干扰,这样就彻底解决了明文存放账号密码的问题。

    以上只是以新浪微博为例,概括了一种最常见的 OAuth2.0 认证方式,关于 OAuth 更全面的文档,请参见 RFC 6749。阮一峰博客上也写过一篇关于 OAuth 的科普,推荐阅读:《理解OAuth 2.0

    相关文章

      网友评论

      • 星际丶牛仔:博主,有实现过twitter的第三方登录吗?
      • 啊发是也:用java 如何实现新浪微博OAuth认证系统
      • LingoGuo:简单易懂,谢谢分享
      • seafruit:请问有没有git地址?可以分享一下吗?
      • 兔兔小八哥:写的好清楚,感觉一目了然
      • jarvan4dev:了解
      • 6b9f742d23da:最近正在研究,好东西👍
      • 1琥珀川1:学习了
      • rainkong:code 的期限是多久啊 怎么过期 假如用户取消授权呢
        花荣贤弟:@rainkong 使用code换取token是oauth2.0的授权码模式,换取的过程是拿到code之后自动执行的,没有过期的概念
        耗子吴:@rainkong 一般拿到 code 要立即换取 token,官方没说过期时间是多少,token的过期时间一般是 7 天,用户取消授权需要重新授权
      • 117b04aca5c2:最近真好在弄这个
      • 9f332f87691f:准确无误
      • 751a08e3b8a9:准确 还附带api例子
      • CameronBurne:之前还处理过refresh_token
        耗子吴:@Kid_Wang refresh_token 算是标准 OAuth 协议中的一部分,但是新浪微博给去掉了,只有移动端使用官方 SDK 才会有
      • SeanKChan:这几天正在做新浪微博,多谢分享

      本文标题:OAuth 认证流程详解

      本文链接:https://www.haomeiwen.com/subject/srelcttx.html