后端与系统架构3541 字
一口气讲完OAuth2四种授权模式
·全库 563 / 611
《一口气讲完OAuth2四种授权模式》共 0.4 万字,通篇围绕 数据库、权限、安全、日志 展开,归在「后端与系统架构」这一层。
覆盖数据库权限安全日志场景Redis
适合给 AI 系统搭底座、要管得住的人
目录骨架(8 节)
- 应用场景
- 名词定义
- 认证流程
- 依赖引入
- 资源服务
- 认证服务
- 授权码模式
- 简化模式
示例代码
📎 附件:oauth-demo.zip(zip, 32KB)
原文链接:https://www.yuque.com/attachments/yuque/0/2024/zip/2424104/1715734317687-b7ebc1ea-727e-4d55-b751-0d1670d6bd0c.zip
jdk版本:1.8.0_181
本次分享内容
- OAuth2概念和流程
- OAuth2项目实战
- OAuth2四种授权模式(授权码模式、简化模式、密码模式、客户端模式)
- 总结
理论
OAuth是一个关于授权(authorization)的开放网络标准,用来授权第三方应用获取用户数据,是目前最流行的授权机制,它当前的版本是 2.0。
应用场景
假如你正在 “网站 A” 上冲浪,看到一篇帖子表示非常喜欢,当你情不自禁的想要点赞时,它会提示你进行登录操作。

打开登录页面你会发现,除了最简单的账户密码登录外,还为我们提供了微博、微信、QQ 等快捷登录方式。假设选择了快捷登录,它会提示我们扫码或者输入账号密码进行登录。

登录成功之后便会将 QQ / 微信的昵称和头像等信息回填到 “网站 A” 中,此时你就可以进行点赞操作了。
名词定义
在详细讲解oauth2之前,我们先来了解一下它里边用到的名词定义吧:
- Client:客户端,它本身不会存储用户快捷登录的账号和密码,只是通过资源拥有者的授权去请求资源服务器的资源,即例子中的网站 A;
- Resource Owner:资源拥有者,通常是用户,即例子中拥有 QQ / 微信账号的用户;
- Authorization Server:认证服务器,可以提供身份认证和用户授权的服务器,即给客户端颁发token和校验token;
- Resource Server:资源服务器,存储用户资源的服务器,即例子中的 QQ / 微信存储的用户信息;
认证流程

如图是oauth2官网的认证流程图,我们来分析一下:
- A 客户端向资源拥有者发送授权申请;
- B 资源拥有者同意客户端的授权,返回授权码;
- C 客户端使用授权码向认证服务器申请令牌token;
- D 认证服务器对客户端进行身份校验,认证通过后发放令牌;
- E 客户端拿着认证服务器颁发的令牌去资源服务器请求资源;
- F 资源服务器校验令牌的有效性,返回给客户端资源信息;
为了大家更好的理解,我们看下面这张图

到这儿,相信大家对理论知识已经掌握的差不多了,接下来我们就进入实战训练吧。
实战
在正式开始搭建项目之前我们先来做一些准备工作:要想使用oauth2的服务,我们得先创建几张表。
数据库
oauth2相关的建表语句可以参考官方初始化 sql,也可以查看项目中的 init.sql 文件

至于表结构,大家可以先大体了解下,其中字段的含义,在 init.sql 文件中已经做了说明。
- oauth_client_details:存储客户端的配置信息,操作该表的类主要是JdbcClientDetailsService.java;
- oauth_access_token:存储生成的令牌信息,操作该表的类主要是JdbcTokenStore.java;
- oauth_client_token:在客户端系统中存储从服务端获取的令牌数据,操作该表的类主要是JdbcClientDetailsService.java;
- oauth_code:存储授权码信息与认证信息,即只有grant_type为authorization_code时,该表才会有数据,操作该表的类主要是JdbcAuthorizationCodeServices.java;
- oauth_approvals:存储用户的授权信息;
- oauth_refresh_token:存储刷新令牌的refresh_token,如果客户端的grant_type不支持refresh_token,那么不会用到这张表,操作该表的类主要是JdbcTokenStore;
在oauth_client_details表中添加一条数据
client_id:cheetah_one //客户端名称,必须唯一
resource_ids:product_api //客户端所能访问的资源id集合,多个资源时用逗号(,)分隔
client_secret:$2a$10$h/TmLPvXozJJHXDyJEN22ensJgaciomfpOc9js9OonwWIdAnRQeoi //客户端的访问密码
scope:read,write //客户端申请的权限范围,可选值包括read,write,trust。若有多个权限范围用逗号(,)分隔
authorized_grant_types:client_credentials,implicit,authorization_code,refresh_token,password //指定客户端支持的grant_type,可选值包括authorization_code,password,refresh_token,implicit,client_credentials, 若支持多个grant_type用逗号(,)分隔
web_server_redirect_uri:http://www.baidu.com //客户端的重定向URI,可为空, 当grant_type为authorization_code或implicit时, 在Oauth的流程中会使用并检查与注册时填写的redirect_uri是否一致
access_token_validity:43200 //设定客户端的access_token的有效时间值(单位:秒),可选, 若不设定值则使用默认的有效时间值(60 * 60 * 12, 12小时)
autoapprove:false //设置用户是否自动Approval操作, 默认值为 'false', 可选值包括 'true','false', 'read','write'