概述

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

@Autowired
private UserService userService;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManagerBean) //使用密码模式需要配置
// .tokenStore(tokenStore) //指定token存储到redis
.reuseRefreshTokens(false) //refresh_token是否重复使用
.userDetailsService(userService) //刷新令牌授权包含对用户信息的检查
.allowedTokenEndpointRequestMethods(HttpMethod.GET,HttpMethod.POST); //支持GET,POST请求
}

@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

/**
*授权码模式
*http://localhost:8080/oauth/authorize?response_type=code&client_id=client&redirect_uri=http://www.baidu.com&scope=all
*http://localhost:8080/oauth/authorize?response_type=code&client_id=client
*
* password模式
* http://localhost:8080/oauth/token?username=fox&password=123456&grant_type=password&client_id=client&client_secret=123123&scope=all
*
* 客户端模式
* http://localhost:8080/oauth/token?grant_type=client_credentials&scope=all&client_id=client&client_secret=123123
*/
clients.inMemory()
//配置client_id
.withClient("client")
//配置client-secret
.secret(passwordEncoder.encode("123123"))
//配置访问token的有效期
.accessTokenValiditySeconds(3600)
//配置刷新token的有效期
.refreshTokenValiditySeconds(864000)
//配置redirect_uri,用于授权成功后跳转
.redirectUris("http://www.baidu.com")
//配置申请的权限范围
.scopes("all")
/**
* 配置grant_type,表示授权类型
* authorization_code: 授权码
* password: 密码
* client_credentials: 客户端
* refresh_token: 更新令牌
*/
.authorizedGrantTypes("authorization_code","password","client_credentials","refresh_token");
}

代码地址

​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秒

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

用过期的token去访问user服务

当token过期之后用过期的token去访问我们的目标服务的时候会报下面的错误
OAuth2.0用refresh_token更新access_token令牌_服务器

刷新token

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

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


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

OAuth2.0用refresh_token更新access_token令牌_java_02

注意,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已经被使用了一次了,第二次使用的时候会返回下面的结果:

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

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

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