【发布时间】:2020-02-04 21:14:59
【问题描述】:
我正在使用 Doorkeeper 5.2.1,我咨询了 Doorkeeper docs on refresh tokens,并阅读了几个与刷新令牌相关的 GitHub 问题和拉取请求,特别是 here 和 here。
根据我从这些对话和阅读规范中收集到的信息(以及documents and posts referencing the spec,以下陈述是正确的:
- 刷新令牌的寿命很长(与访问令牌相反,访问令牌通常在相对较短的 TTL 后过期)
- 授权服务器可以实现撤销
- Doorkeeper 在某些基础上实现了刷新令牌撤销(虽然我不清楚是什么,请继续阅读)
不过,我很困惑,基于this pull request,它在“使用该刷新令牌创建的访问令牌成功使用一次”后实现刷新令牌到期。 Doorkeeper 如何知道我是否已成功使用该访问令牌发出 API 请求?我的 API 根据该访问令牌计算出授权逻辑。 Doorkeeper 不知道我的 API 请求是否成功。但是,我将其解释为如果 resource_owner_authenticator 块返回用户,则可能构成成功使用。但是我还没有发现刷新令牌成功过期。 (请参阅下面的规范。)
从阅读this spec file 中也可以看出,如果您成功使用了刷新令牌,它会撤销之前的刷新令牌,这是有道理的。
不过,我正在尝试在我的规范文件中解决所有这些问题,但我遇到了一个问题,即刷新令牌似乎没有被撤销,即使它被多次使用,或者它( “刷新令牌A”)在之后被重用,刷新令牌(“令牌B”)与刷新令牌A用于生成的访问令牌一起返回,也被使用。我的规范文件会更清楚地说明这一点:
describe 'OAuth flow' do
# ...
describe 'refresh tokens' do
# ...
context 'when attempting reuse of a refresh token' do
before do
redirect_uri = 'https://localhost:3002'
# ivars necessary brecause plaintext tokens/secrets are only available upon creation of the object
@client = Doorkeeper::Application.create(name: 'foo', uid: 'bar', redirect_uri: redirect_uri, scopes: 'project_index')
@secret = @client.plaintext_secret
@grant = Doorkeeper::AccessGrant.create(resource_owner_id: user.id, organization_id: org.id, application_id: @client.id, scopes: 'project_index', expires_in: 600, redirect_uri: redirect_uri)
@code = @grant.plaintext_token
end
it 'revokes the initial refresh token' do
# Get an initial access token and refresh token
post "/oauth/token?client_id=#{@client.uid}&client_secret=#{@secret}&code=#{@code}&grant_type=authorization_code&redirect_uri=#{@client.redirect_uri}&scope=project_index"
expect(response.status).to eq(200)
# Use refresh token to get a new access token
previous_refresh_token = JSON.parse(response.body)['refresh_token']
post "/oauth/token?client_id=#{@client.uid}&client_secret=#{@secret}&code=#{@code}&grant_type=refresh_token&refresh_token=#{previous_refresh_token}&redirect_uri=#{@client.redirect_uri}&scope=project_index"
expect(response.status).to eq(200)
json_body = JSON.parse(response.body)
new_access_token = json_body['access_token']
new_refresh_token = json_body['refresh_token']
# Use the new access token successfully
get "/api/v1/projects?access_token=#{new_access_token}"
expect(response.status).to eq(200)
# Use the new refresh token to get yet another access token
post "/oauth/token?client_id=#{@client.uid}&client_secret=#{@secret}&code=#{@code}&grant_type=refresh_token&refresh_token=#{new_refresh_token}&redirect_uri=#{@client.redirect_uri}&scope=project_index"
expect(response.status).to eq(200)
# Attempt reuse of the first refresh token
post "/oauth/token?client_id=#{@client.uid}&client_secret=#{@secret}&code=#{@code}&grant_type=refresh_token&refresh_token=#{previous_refresh_token}&redirect_uri=#{@client.redirect_uri}&scope=project_index"
expect(response.status).to eq(400)
# ^^^ fails, response is 200 and a new access token and refresh token are generated
end
end
end
# ...
end
此规范在最后一个断言上失败,表明对于给定的刷新令牌,当它用于生成的访问令牌被成功使用时(与上述相反),或者当刷新令牌发出时,它不会被撤销使用刷新的访问令牌。
我的问题是,对于 Doorkeeper,在什么情况下会撤销刷新令牌?
【问题讨论】:
标签: ruby-on-rails ruby doorkeeper