V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
linbomb
V2EX  ›  PHP

oauth 协议里 request token 和 access token 的疑问?

  •  
  •   linbomb · 2015-09-14 19:45:14 +08:00 · 4482 次点击
    这是一个创建于 3366 天前的主题,其中的信息可能已经有所发展或是发生改变。

    ( A )用户打开客户端以后,客户端要求用户给予授权。
    ( B )用户同意给予客户端授权。
    ( C )客户端使用上一步获得的授权,向认证服务器申请令牌。
    ( D )认证服务器对客户端进行认证以后,确认无误,同意发放令牌。
    ( E )客户端使用令牌,向资源服务器申请获取资源。
    ( F )资源服务器确认令牌无误,同意向客户端开放资源。

    看了一下 oauth 协议的流程, request token 的作用是什么,用户授权之后为什么不直接返回 access token ?
    求高手解答一下。

    8 条回复    2018-07-30 16:33:18 +08:00
    ipconfiger
        1
    ipconfiger  
       2015-09-14 20:21:23 +08:00
    客户端获取到一次性密码通过服务端获取 accesstoken ,就不用传输密码啦
    batman2010
        2
    batman2010  
       2015-09-14 20:33:14 +08:00 via Android
    用户授权表示用户同意第三方 app 使用 OAuth 登录,但这个时候还没输入账号密码,所以不能给 access token 。
    hantsy
        3
    hantsy  
       2015-09-14 20:40:53 +08:00   ❤️ 1
    @linbomb
    参考 oauth.net 官方,有详细的介绍。

    oauth 1.x 和 oauth 2 还是有差别的, oauth 2 现在是主流, 相对简单一些,有好几种使用方式,适用于不同场景。

    @ipconfiger
    oAuth 2 常见认证可以是 3 legs, 也可以是 2 legs.

    Oauth2 如果使用 code 方式,先需要取得一个临时的 Authorization Code ,然后再用这个 code 去取 token. 然后使用 token 访问受限的资源。

    implicit 方式更简单一些,直接取得 token.
    jkeylu
        4
    jkeylu  
       2015-09-14 21:07:55 +08:00 via Android
    request token 是用来验证客户端的,相当于告诉服务器我是哪个客户端

    至于为什么不直接返回 access token?是因为如果使用 code 方式的话,服务器获得用户授权后通过 302 跳转到你的 callback URI 上,并在 url query 上带上用于交换 accesd token 的 code 。


    可想而知这个 url query 上的 code 是很有可能不可信的代码会应用获取,(不严谨的省略一万字)所以在 url 上直接返回 access token 是不安全的。

    所以,客户端获得 code 后,再用它去和服务器交换 access token 。

    如果这个 app 是一个完全可信的应用,就可以直接用 implicit 方式直接获得 access token 。

    ps:个人理解,不一定正确
    harrychuh
        5
    harrychuh  
       2015-09-14 21:19:52 +08:00 via Android   ❤️ 1
    Request token 是鉴权阶段的开始, oauth 的目的就是要让第三方在不知道用户名密码的情况下完成鉴权,但是没有密码用户名组合根本不可能有效鉴权, oauth 实际的过程是一个李代桃疆的手法,在第一方用你的原始用户名和密码组合,生成另外一对名称密码组合,这个阶段叫做获取 code 和 state,这对组合送到第二方也就是你的资源所在地,同样较验一遍,如果合格,给你生成一个带有时效性的 access token,你玩儿的那个应用就是第三方在有效期内拿着这个 access token 跳过第一方直接请求第二方的资源。

    还是有点绕嗬,你姓尔名康,正在玩萧剑,萧剑想拜访紫薇,但是你不愿意给萧剑你的钥匙,于是你们一起走到俗语喧门卫那里,门卫只认你和你的钥匙,发现匹配,问你是不是允许萧剑也勾搭紫薇,你说 ok 啦,于是给你一副腰牌 code 一张跟腰牌匹配的纸巾 state ,右手一指 redirect 二楼 B 房间,你俩去了,门口坐着冬雨荷阿姨,你递上腰牌与纸巾,阿姨闻了一下较验,给你一个排号 745388ZIWEI,你俩就进入了,然后你去找永妻玩去了,而萧剑只要拿着这个号码牌进进出出都没有问题,冬雨荷阿姨都放行的
    Gonster
        6
    Gonster  
       2015-09-14 21:38:44 +08:00
    @harrychuh 好亮...
    linbomb
        7
    linbomb  
    OP
       2015-09-15 10:35:08 +08:00
    @hantsy 感谢回答。
    其实我是不明白 code 方式是否多余,服务器先给我 code ,然后我拿 code 取 token 。
    假如是因为认证服务器和资源服务器分离,这两个服务器需要交互,那这些过程为什么不在服务端完成。
    还是不太理解 code 的意义,好像 code 只是为了拿 token 。
    mingszu
        8
    mingszu  
       2018-07-30 16:33:18 +08:00
    这里有讲
    https://stackoverflow.com/questions/13387698/why-is-there-an-authorization-code-flow-in-oauth2-when-implicit-flow-works-s

    大概讲的是授权服务器会重定向到你所指定的 url,但是重定向没有 body 只能通过 URL 里拼接传参数,这样带来安全问题;而客户端服务器根据授权码向授权服务器发请求,它们之间的交流可以不通过 URL 传参数,可以通过 hash 段 access Token,hash 段不属于 http 请求它只能被浏览器所识别因此不能被中间人获取

    除此之外,我自己的一些看法:
    1.客户端会暴露 token
    授权服务器是会根据客户端传来的 redirect_url 返回给客户端 3xx 重定向状态码,然后客户端再把授权码 code 传给客户端服务器,首先前端的都是不安全的,直接将 token 传给客户端会把 token 暴露,坏人就可以获取拿来干坏事了

    2.授权服务器不会直接发 token
    所有授权客户都需要向授权中心注册获取 appkey 与 appscrete,其中 appkey 为公开的而 appscrete 是只有客户端与服务器可见的,更重要的是 appscrete 只能存在客户端服务器不能直接存在客户端上不然同样会暴露。
    因此客户端向授权中心申请授权时会发送自己的 appkey,然后授权中心会返回授权码,经过重定向到客户端服务器,客户端服务器申请授权时要将 appscrete 一起传给授权服务器,授权服务器一一对比确认无误后才会发放 token。
    如果客户端只发送 appkey 就能直接获取 token,那么所有人都可以模拟该客户端来获取 token 了,这得多可怕
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1218 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 17:58 · PVG 01:58 · LAX 09:58 · JFK 12:58
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.