概述

使用oauth2时,如果令牌失效了,可以使用刷新令牌通过refresh_token的授权模式再次获取access_token。只需修改认证服务器的配置,添加refresh_token的授权模式即可。
修改授权服务器配置,增加refresh_token配置

  1. @Autowired
  2. private UserService userService;
  3. @Override
  4. public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
  5. endpoints.authenticationManager(authenticationManagerBean) //使用密码模式需要配置
  6. // .tokenStore(tokenStore) //指定token存储到redis
  7. .reuseRefreshTokens(false) //refresh_token是否重复使用
  8. .userDetailsService(userService) //刷新令牌授权包含对用户信息的检查
  9. .allowedTokenEndpointRequestMethods(HttpMethod.GET,HttpMethod.POST); //支持GET,POST请求
  10. }
  11. @Override
  12. public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
  13. /**
  14. *授权码模式
  15. *http://localhost:8080/oauth/authorize?response_type=code&client_id=client&redirect_uri=http://www.baidu.com&scope=all
  16. *http://localhost:8080/oauth/authorize?response_type=code&client_id=client
  17. *
  18. * password模式
  19. * http://localhost:8080/oauth/token?username=fox&password=123456&grant_type=password&client_id=client&client_secret=123123&scope=all
  20. *
  21. * 客户端模式
  22. * http://localhost:8080/oauth/token?grant_type=client_credentials&scope=all&client_id=client&client_secret=123123
  23. */
  24. clients.inMemory()
  25. //配置client_id
  26. .withClient("client")
  27. //配置client-secret
  28. .secret(passwordEncoder.encode("123123"))
  29. //配置访问token的有效期
  30. .accessTokenValiditySeconds(3600)
  31. //配置刷新token的有效期
  32. .refreshTokenValiditySeconds(864000)
  33. //配置redirect_uri,用于授权成功后跳转
  34. .redirectUris("http://www.baidu.com")
  35. //配置申请的权限范围
  36. .scopes("all")
  37. /**
  38. * 配置grant_type,表示授权类型
  39. * authorization_code: 授权码
  40. * password: 密码
  41. * client_credentials: 客户端
  42. * refresh_token: 更新令牌
  43. */
  44. .authorizedGrantTypes("authorization_code","password","client_credentials","refresh_token");
  45. }

代码地址

https://gitee.com/zjj19941/ZJJ_Neaten5.10/tree/master/ZJJ_SpringCloud_Oauth2/demo03

测试

获取token

get请求:
http://localhost:8080/oauth/token?username=fox&password=123456&grant_type=password&client_id=client&client_secret=123123&scope=all

结果:
可以发现access_token的有效时间只有59秒

  1. {
  2. "access_token": "f2eec987-bc8a-404d-9d77-3eecfe2c5fb0",
  3. "token_type": "bearer",
  4. "refresh_token": "162b1497-8880-4cc2-afe1-2c8bba82026c",
  5. "expires_in": 59,
  6. "scope": "all"
  7. }

用过期的token去访问user服务

当token过期之后用过期的token去访问我们的目标服务的时候会报下面的错误
image.png

刷新token



get请求: http://localhost:8080/oauth/token?grant_type=refresh_token&client_id=client&client_secret=123123&refresh_token=162b1497-8880-4cc2-afe1-2c8bba82026c

  1. {
  2. "access_token": "982e6883-9f03-4840-9869-cbaba5414339",
  3. "token_type": "bearer",
  4. "refresh_token": "6bf21179-5e36-4306-9cdb-979db69612f1",
  5. "expires_in": 59,
  6. "scope": "all"
  7. }

用新的token就可以正常的访问user服务了

image.png

注意,refresh_token可以设置是否重用

http://localhost:8080/oauth/token?grant_type=refresh_token&client_id=client&client_secret=123123&refresh_token=162b1497-8880-4cc2-afe1-2c8bba82026c

如果refresh_token已经被使用了一次了,第二次使用的时候会返回下面的结果:

  1. {
  2. "error": "invalid_grant",
  3. "error_description": "Invalid refresh token: 162b1497-8880-4cc2-afe1-2c8bba82026c"
  4. }

设置refresh_token是否重复使用 reuseRefreshTokens(false) false就是不可以重用,

  1. @Override
  2. public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
  3. // 认证管理器去SpringSecurity做用户名密码认证.
  4. endpoints.authenticationManager(authenticationManagerBean) //使用密码模式需要配置
  5. // token存储策略 , 指定token存储到redis
  6. .tokenStore(tokenStore)
  7. .reuseRefreshTokens(false) //refresh_token是否重复使用
  8. .userDetailsService(userService) //刷新令牌授权包含对用户信息的检查
  9. .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST); //支持GET,POST请求
  10. }