为何OAuth不直接向客户端返回Access Token而保留授权码交换流程?
你的疑问很直接——既然授权码也要通过浏览器传输,那为啥不直接返回AccessToken省掉交换步骤?其实这个多出来的步骤核心是降低风险影响范围,具体来说有这几个关键原因:
授权码的风险远低于AccessToken
授权码通常是一次性的,且有效期极短(比如1-5分钟),就算被攻击者窃取,可用的时间窗口非常小,而且用一次就作废,没法重复换取AccessToken。但AccessToken是长期有效的(可能几小时甚至几天),且直接拥有访问用户资源的权限,一旦泄露,攻击者能持续滥用直到token过期。客户端身份验证的关卡
在换取AccessToken的步骤中,保密类型的客户端(比如后端服务)需要向授权服务器提交自己的client_secret,服务器会先验证客户端的合法性,再发放AccessToken。就算攻击者拿到了授权码,没有对应的client_secret也换不到有效的AccessToken。而如果直接把AccessToken返回给浏览器,任何拿到这个token的人都能直接用,完全绕开了客户端身份验证。减少AccessToken的暴露场景
授权码是通过重定向URL传递的,确实会出现在浏览器历史、跳转日志里,但AccessToken是通过后端的HTTPS POST请求(通常放在请求体里)完成交换的,不会暴露在URL中,也不会被前端页面的脚本轻易获取(比如XSS攻击如果拿到前端存储的AccessToken危害极大,但授权码就算被XSS拿到,没有client_secret也没用)。
简单说,授权码更像一张“一次性取件码”,就算丢了,别人没你的取件身份(client_secret)也拿不到包裹(AccessToken),而且取件码很快过期;而直接给AccessToken相当于把包裹直接递到大街上,谁捡到都能拿走用。
内容的提问来源于stack exchange,提问作者Simon

