一文讲清楚 OAuth 2.0 支持的四个授权流程
目录
1、授权码授权流程(Authorization Code Grant)
2、隐式授权流程(Implicit Grant)
3、密码凭证授权流程(Resource Owner Password Credentials Grant)
4、客户端凭证授权流程(Client Credentials Grant)
OAuth 2.0协议支持多种授权流程(Authorization Grant Types),用于实现在不同场景下的授权。在开始讲解前,再罗列一下 OAuth 2.0 中的几个参与方,在正文中使用的关键概念一定要和这里的对齐,千万不要按照自己认为的意思去理解。
- Resource Owner(资源所有者):资源的拥有者,通常是终端用户。资源可以是用户数据、照片、视频等。
- Client(客户端,还有另外一种叫法是 Relying party):请求访问受保护资源的第三方应用。客户端可以是 Web 应用、移动应用或桌面应用。
- Authorization Server(授权服务器):负责验证资源所有者的身份并颁发 Access Token 给客户端的服务器。
- Resource Server(资源服务器):存储受保护资源的服务器,可以接收并响应使用 Access Token 访问的请求。很多企业和组织在实现的时候,会把 Resource Server 和 Authorization Server 做在一个服务里面。
1、授权码授权流程(Authorization Code Grant)
这是推荐的也是最安全的 OAuth 2.0 授权流程,授权过程如下:
- 客户端向授权服务器请求授权:客户端重定向用户到授权服务器并请求授权。包括客户端标识、请求的范围(Scope)等信息。
- 用户授权:资源所有者登录并授权客户端访问其受保护资源。
- 授权服务器颁发授权码:如果资源所有者同意授权,授权服务器将重定向用户到客户端并附带一个授权码。
- 客户端通过授权码获取 Access Token:客户端使用授权码向授权服务器请求 Access Token(通过云对云的 API 调用来完成)。
- 授权服务器颁发 Access Token:授权服务器验证授权码,并颁发 Access Token 给客户端。
- 客户端使用 Access Token 访问资源服务器:客户端使用 Access Token 向资源服务器请求访问受保护资源(通过云对云的 API 调用来完成)。
优点:
- 安全性高,因为 Access Token 存储在后端,不会直接暴露给前端。
- 支持 Refresh Token,可以长期维持用户会话而无需再次让用户输入凭证。
使用场景:
适用于有后端服务器的应用程序,特别是那些需要代表用户执行操作的第三方应用。
2、隐式授权流程(Implicit Grant)
授权过程:
- 客户端向授权服务器请求授权:客户端重定向用户到授权服务器并请求授权。包括客户端标识、请求的范围(Scope)等信息。
- 用户授权:资源所有者登录并授权客户端访问其受保护资源。
- 授权服务器颁发授权码:如果资源所有者同意授权,授权服务器将重定向用户到客户端并附带 Access Token。
- 客户端使用 Access Token 访问资源服务器:客户端使用 Access Token 向资源服务器请求访问受保护资源。
缺点:
- 安全性较低,因为 Access Token 直接暴露在浏览器中。
- 不支持 Refresh Token,一旦 Access Token 过期,用户需要重新授权。
使用场景:适用于无后端服务器的应用,例如完全运行在浏览器中的单页应用(SPA)、无后端服务的移动应用等。
3、密码凭证授权流程(Resource Owner Password Credentials Grant)
授权过程:
- 用户直接向客户端提供自己的用户名和密码。
- 客户端使用这些凭证直接向授权服务器请求 Access Token。
- 授权服务器验证凭证。
- 如果验证成功,授权服务器向客户端返回 Access Token。
缺点:
- 安全性非常低,客户端使了用户的用户名和密码,,增加了泄露风险。
- 不符合 OAuth 2.0不共享用户凭证的设计理念。
使用场景:仅限于用户与客户端之间存在高度信任关系的情况,如企业内部应用或第一方应用
4、客户端凭证授权流程(Client Credentials Grant)
授权过程:
- 客户端直接向授权服务器发送客户端 ID 和客户端密钥。
- 授权服务器验证客户端的身份。
- 如果验证成功,授权服务器向客户端返回 Access Token。
缺点:
- 客户端密钥泄露可能导致安全问题。
- 不适用于需要用户授权的场景。
使用场景:适用于客户端需要访问自己的资源或公共数据,而无需用户参与的情况。例如服务器端到服务器端的应用程序通信和访问不需要用户上下文的资源。