OAuth2源码分析之 常见面试问题总结回答二 access_token 与 refresh_token

686 阅读2分钟

持续更新Oauth2源码过程

1 . access_token生成过程/生成算法/如何判断是否过期

 1.1 client第三方应用访问认证服务器获取授权码请求:localhost:7777/oauth/authorize?client_id=cms&response_type=code
 1.2 跳转到认证服务器登陆页面,根据认证服务器预先颁发的账号,密匙登陆认证服务器,进入到授权页面
 

企业微信截图_32c48ef6-4ad3-417a-95b0-c1234b90c4c6.png

 1.3点击授权,生成访问code=j73nPp

企业微信截图_acf36a73-712b-4867-ae9a-1ecf539f3ed5.png

企业微信截图_753159bc-36fc-4992-a95e-4024c196f6a0.png

1.4 调用根据授权码获取access_token请求: http://localhost:7777/oauth/token?grant_type=authorization_code&code=j73nPp&client_id=cms&client_secret=secret 开始追踪源码
---> 进入到controller类 TokenEndpoint 
OAuth2AccessToken token = getTokenGranter().grant(tokenRequest.getGrantType(), tokenRequest);

企业微信截图_1252e9b0-5d56-4442-93ec-1edd45038d0b.png

---> tokenServices.createAccessToken(getOAuth2Authentication(client, tokenRequest));

企业微信截图_232c1a8f-d8a0-4cb6-8306-1424d9474d2d.png

--->InMemoryAuthorizationCodeServices取出对应保存的 授权码:访问信息 

企业微信截图_d38279b9-9e46-4691-8b83-97810da065d8.png

---->OAuth2AccessToken existingAccessToken = tokenStore.getAccessToken(authentication); 通过访问信息判断是否已经存在此access_token existingAccessToken

企业微信截图_22decd0e-7f93-41ec-85fd-c5211d747cda.png

----> 先创建refresh_token 再 OAuth2AccessToken accessToken = createAccessToken(authentication, refreshToken);创建对应的access_token

企业微信截图_fe83569e-ed43-4803-b7c1-6e91861d9cae.png

继续追踪 DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken(UUID.randomUUID().toString());生成access_token
也就是access_token其实生成算法是 UUID.randomUUID().toString()

企业微信截图_145a006b-a765-4864-ae69-f70ec0abd520.png

--->对access_token进行丰富 例如设置过期时间,默认是12小时,授权范围
     以及设置refresh_token 
     

企业微信截图_8f0473ae-fdd3-4b9f-8336-2ef5f5a07b67.png

--->保存refresh_token

企业微信截图_78168162-1ab8-4881-878d-f78e06e1f085.png

---> over 返回结果 

企业微信截图_af679d66-d36d-42a4-aa82-5b093ad58968.png

2. 创建access_token过程中,为什么还有个refresh_token,有什么作用意义?

 假设场景: 用户A在微博客户端,想访问QQ的相册,在OAuth2流程中表现形式,
          1 微博端跳转到QQ端页面进行登陆授权
          2 获取到QQ端的允许权限
          3 微博得到一个access_token 进行api访问
          
 缺陷场景 : 从安全的角度,会生成的access_token设置过期时间,例如我们设置这个access_token的过期时间为3分钟,那么相当于3分钟过后失效,3分钟后,用户A又得重复步骤 1,2,3 频繁打开QQ端 获取允许权限, 体验感极差,用户内心(what? see you rubbish)
 
 refresh_token: 因此为了有效避免上述的缺陷,OAuth2 整出了这个双token机制
 
 作用解释: 后续过程中,微博端 直接通过 refresh_token来获取,刷新过期/未过期的 access_token,不用再频繁打开QQ端获取允许权限
 
 

附. refresh_token 作用示例demo

 上述我们回答了refresh_token的作用,这里也是搭建了一个demo工程做个功能演示
 
 3.1 配置OAuth2 
public class OAuth2Configuration extends AuthorizationServerConfigurerAdapter {

//自定义拓展的鉴权类
@Autowired
private SecurityUserDetailsService securityUserDetailsService;

/**
* 用来配置授权(authorization)以及令牌(token)的访问端点和令牌服务(token services)
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
   // 使用内存保存生成的token
endpoints.authenticationManager(authenticationManager).tokenStore(memoryTokenStore());
endpoints.userDetailsService(securityUserDetailsService);
}
3.2 获取refresh_token http://localhost:7777/oauth/token?grant_type=authorization_code&code=gaZbvA&client_id=cms&client_secret=secret

企业微信截图_b3818cd9-a553-49f6-a8c3-f1502a3ee2b7.png

 3.3 通过refresh_token获取access_token http://localhost:7777/oauth/token?grant_type=refresh_token&client_id=cms&client_secret=secret&refresh_token=56149766-fc14-471d-afee-5b1492e64e28
 

企业微信截图_01775c79-a6df-48b7-bcfc-ad5685199c25.png

 3.4 校验步骤3.3 获取的access_token是否有效/校验成功
  

企业微信截图_001f4351-552f-4c4b-9d7f-9134a1dd5b88.png

备注

refresh_token 源码演示demo下载

后续补充refresh_token 作用源码过程