Merge pull request #1056 from uhoreg/refresh_token_spec

Add spec for refresh tokens
pull/1110/head
Hubert Chathi 3 years ago committed by GitHub
commit 8d82366cf2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1 @@
Add refresh tokens, per [MSC2918](https://github.com/matrix-org/matrix-spec-proposals/pull/2918).

@ -71,7 +71,7 @@ These error codes can be returned by any API endpoint:
Forbidden access, e.g. joining a room without permission, failed login. Forbidden access, e.g. joining a room without permission, failed login.
`M_UNKNOWN_TOKEN` `M_UNKNOWN_TOKEN`
The access token specified was not recognised. The access or refresh token specified was not recognised.
An additional response parameter, `soft_logout`, might be present on the An additional response parameter, `soft_logout`, might be present on the
response for 401 HTTP status codes. See [the soft logout response for 401 HTTP status codes. See [the soft logout
@ -314,7 +314,8 @@ Most API endpoints require the user to identify themselves by presenting
previously obtained credentials in the form of an `access_token` query previously obtained credentials in the form of an `access_token` query
parameter or through an Authorization Header of `Bearer $access_token`. parameter or through an Authorization Header of `Bearer $access_token`.
An access token is typically obtained via the [Login](#login) or An access token is typically obtained via the [Login](#login) or
[Registration](#account-registration-and-management) processes. [Registration](#account-registration-and-management) processes. Access tokens
can expire; a new access token can be generated by using a refresh token.
{{% boxes/note %}} {{% boxes/note %}}
This specification does not mandate a particular format for the access This specification does not mandate a particular format for the access
@ -338,40 +339,94 @@ inaccessible for the client.
When credentials are required but missing or invalid, the HTTP call will When credentials are required but missing or invalid, the HTTP call will
return with a status of 401 and the error code, `M_MISSING_TOKEN` or return with a status of 401 and the error code, `M_MISSING_TOKEN` or
`M_UNKNOWN_TOKEN` respectively. `M_UNKNOWN_TOKEN` respectively. Note that an error code of `M_UNKNOWN_TOKEN`
could mean one of four things:
1. the access token was never valid.
2. the access token has been logged out.
3. the access token has been [soft logged out](#soft-logout).
4. {{< added-in v="1.3" >}} the access token [needs to be refreshed](#refreshing-access-tokens).
When a client receives an error code of `M_UNKNOWN_TOKEN`, it should:
- attempt to [refresh the token](#refreshing-access-tokens), if it has a refresh
token;
- if [`soft_logout`](#soft-logout) is set to `true`, it can offer to
re-log in the user, retaining any of the client's persisted
information;
- otherwise, consider the user as having been logged out.
### Relationship between access tokens and devices ### Relationship between access tokens and devices
Client [devices](../index.html#devices) are closely related to access Client [devices](../index.html#devices) are closely related to access
tokens. Matrix servers should record which device each access token is tokens and refresh tokens. Matrix servers should record which device
assigned to, so that subsequent requests can be handled correctly. each access token and refresh token are assigned to, so that
subsequent requests can be handled correctly. When a refresh token is
used to generate a new access token and refresh token, the new access
and refresh tokens are now bound to the device associated with the
initial refresh token.
By default, the [Login](#login) and [Registration](#account-registration-and-management) By default, the [Login](#login) and [Registration](#account-registration-and-management)
processes auto-generate a new `device_id`. A client is also free to processes auto-generate a new `device_id`. A client is also free to
generate its own `device_id` or, provided the user remains the same, generate its own `device_id` or, provided the user remains the same,
reuse a device: in either case the client should pass the `device_id` in reuse a device: in either case the client should pass the `device_id` in
the request body. If the client sets the `device_id`, the server will the request body. If the client sets the `device_id`, the server will
invalidate any access token previously assigned to that device. There is invalidate any access and refresh tokens previously assigned to that device.
therefore at most one active access token assigned to each device at any
one time. ### Refreshing access tokens
{{% added-in v="1.3" %}}
Access tokens can expire after a certain amount of time. Any HTTP calls that
use an expired access token will return with an error code `M_UNKNOWN_TOKEN`,
preferably with `soft_logout: true`. When a client receives this error and it
has a refresh token, it should attempt to refresh the access token by calling
[`/refresh`](#post_matrixclientv3refresh). Clients can also refresh their
access token at any time, even if it has not yet expired. If the token refresh
succeeds, the client should use the new token for future requests, and can
re-try previously-failed requests with the new token. When an access token is
refreshed, a new refresh token may be returned; if a new refresh token is
given, the old refresh token will be invalidated, and the new refresh token
should be used when the access token needs to be refreshed.
The old refresh token remains valid until the new access token or refresh token
is used, at which point the old refresh token is revoked. This ensures that if
a client fails to receive or persist the new tokens, it will be able to repeat
the refresh operation.
If the token refresh fails and the error response included a `soft_logout:
true` property, then the client can treat it as a [soft logout](#soft-logout)
and attempt to obtain a new access token by re-logging in. If the error
response does not include a `soft_logout: true` property, the client should
consider the user as being logged out.
Handling of clients that do not support refresh tokens is up to the homeserver;
clients indicate their support for refresh tokens by including a
`refresh_token: true` property in the request body of the
[`/login`](#post_matrixclientv3login) and
[`/register`](#post_matrixclientv3register) endpoints. For example, homeservers
may allow the use of non-expiring access tokens, or may expire access tokens
anyways and rely on soft logout behaviour on clients that don't support
refreshing.
### Soft logout ### Soft logout
When a request fails due to a 401 status code per above, the server can A client can be in a "soft logout" state if the server requires
include an extra response parameter, `soft_logout`, to indicate if the re-authentication before continuing, but does not want to invalidate the
client's persisted information can be retained. This defaults to client's session. The server indicates that the client is in a soft logout
`false`, indicating that the server has destroyed the session. Any state by including a `soft_logout: true` parameter in an `M_UNKNOWN_TOKEN`
error response; the `soft_logout` parameter defaults to `false`. If the
`soft_logout` parameter is omitted or is `false`, this means the server has
destroyed the session and the client should not reuse it. That is, any
persisted state held by the client, such as encryption keys and device persisted state held by the client, such as encryption keys and device
information, must not be reused and must be discarded. information, must not be reused and must be discarded. If `soft_logout` is
`true` the client can reuse any persisted state.
When `soft_logout` is true, the client can acquire a new access token by {{% changed-in v="1.3" %}} A client that receives such a response can try to
specifying the device ID it is already using to the login API. In most [refresh its access token](#refreshing-access-tokens), if it has a refresh
cases a `soft_logout: true` response indicates that the user's session token available. If it does not have a refresh token available, or refreshing
has expired on the server-side and the user simply needs to provide fails with `soft_logout: true`, the client can acquire a new access token by
their credentials again. specifying the device ID it is already using to the login API.
In either case, the client's previously known access token will no
longer function.
### User-Interactive Authentication API ### User-Interactive Authentication API
@ -1105,6 +1160,8 @@ errcode of `M_EXCLUSIVE`.
{{% http-api spec="client-server" api="login" %}} {{% http-api spec="client-server" api="login" %}}
{{% http-api spec="client-server" api="refresh" %}}
{{% http-api spec="client-server" api="logout" %}} {{% http-api spec="client-server" api="logout" %}}
#### Login Fallback #### Login Fallback

@ -1,5 +1,6 @@
# Copyright 2016 OpenMarket Ltd # Copyright 2016 OpenMarket Ltd
# Copyright 2018 New Vector Ltd # Copyright 2018 New Vector Ltd
# Copyright 2022 The Matrix.org Foundation C.I.C.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -133,6 +134,11 @@ paths:
description: |- description: |-
A display name to assign to the newly-created device. Ignored A display name to assign to the newly-created device. Ignored
if `device_id` corresponds to a known device. if `device_id` corresponds to a known device.
refresh_token:
type: boolean
description: |-
If true, the client supports refresh tokens.
x-addedInMatrixVersion: "1.3"
required: ["type"] required: ["type"]
responses: responses:
@ -142,6 +148,8 @@ paths:
application/json: { application/json: {
"user_id": "@cheeky_monkey:matrix.org", "user_id": "@cheeky_monkey:matrix.org",
"access_token": "abc123", "access_token": "abc123",
"refresh_token": "def456",
"expires_in_ms": 60000,
"device_id": "GHTYAJCE", "device_id": "GHTYAJCE",
"well_known": { "well_known": {
"m.homeserver": { "m.homeserver": {
@ -163,6 +171,23 @@ paths:
description: |- description: |-
An access token for the account. An access token for the account.
This access token can then be used to authorize other requests. This access token can then be used to authorize other requests.
refresh_token:
type: string
description: |-
A refresh token for the account. This token can be used to
obtain a new access token when it expires by calling the
`/refresh` endpoint.
x-addedInMatrixVersion: "1.3"
expires_in_ms:
type: integer
description: |-
The lifetime of the access token, in milliseconds. Once
the access token has expired a new access token can be
obtained by using the provided refresh token. If no
refresh token is provided, the client will need to re-log in
to obtain a new access token. If not given, the client can
assume that the access token will not expire.
x-addedInMatrixVersion: "1.3"
home_server: home_server:
type: string type: string
description: |- description: |-

@ -0,0 +1,108 @@
# Copyright 2022 The Matrix.org Foundation C.I.C.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
swagger: '2.0'
info:
title: "Matrix Client-Server Registration and Login API"
version: "1.0.0"
host: localhost:8008
schemes:
- https
- http
basePath: /_matrix/client/v3
consumes:
- application/json
produces:
- application/json
paths:
"/refresh":
post:
x-addedInMatrixVersion: "1.3"
summary: Refresh an access token
description: |-
Refresh an access token. Clients should use the returned access token
when making subsequent API calls, and store the returned refresh token
(if given) in order to refresh the new access token when necessary.
After an access token has been refreshed, a server can choose to
invalidate the old access token immediately, or can choose not to, for
example if the access token would expire soon anyways. Clients should
not make any assumptions about the old access token still being valid,
and should use the newly provided access token instead.
The old refresh token remains valid until the new access token or refresh token
is used, at which point the old refresh token is revoked.
Note that this endpoint does not require authentication via an
access token. Authentication is provided via the refresh token.
Application Service identity assertion is disabled for this endpoint.
operationId: refresh
parameters:
- in: body
name: body
required: true
schema:
type: object
example: {
"refresh_token": "some_token"
}
properties:
refresh_token:
type: string
description: The refresh token
responses:
200:
description: A new access token and refresh token were generated.
examples:
application/json: {
"access_token": "a_new_token",
"expires_in_ms": 60000,
"refresh_token": "another_new_token"
}
schema:
type: object
properties:
access_token:
type: string
description: |-
The new access token to use.
refresh_token:
type: string
description: |-
The new refresh token to use when the access token needs to
be refreshed again. If not given, the old refresh token can
be re-used.
expires_in_ms:
type: integer
description: |-
The lifetime of the access token, in milliseconds. If not
given, the client can assume that the access token will not
expire.
required:
- access_token
401:
description: |-
The provided token was unknown, or has already been used.
examples:
application/json: {
"errcode": "M_UNKNOWN_TOKEN",
"error": "Soft logged out",
"soft_logout": true
}
schema:
"$ref": "definitions/errors/error.yaml"
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/errors/rate_limited.yaml"

@ -1,4 +1,5 @@
# Copyright 2016 OpenMarket Ltd # Copyright 2016 OpenMarket Ltd
# Copyright 2022 The Matrix.org Foundation C.I.C.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -127,6 +128,11 @@ paths:
returned from this call, therefore preventing an automatic returned from this call, therefore preventing an automatic
login. Defaults to false. login. Defaults to false.
example: false example: false
refresh_token:
type: boolean
description: |-
If true, the client supports refresh tokens.
x-addedInMatrixVersion: "1.3"
responses: responses:
200: 200:
description: The account has been registered. description: The account has been registered.
@ -152,6 +158,27 @@ paths:
An access token for the account. An access token for the account.
This access token can then be used to authorize other requests. This access token can then be used to authorize other requests.
Required if the `inhibit_login` option is false. Required if the `inhibit_login` option is false.
refresh_token:
type: string
description: |-
A refresh token for the account. This token can be used to
obtain a new access token when it expires by calling the
`/refresh` endpoint.
Omitted if the `inhibit_login` option is false.
x-addedInMatrixVersion: "1.3"
expires_in_ms:
type: integer
description: |-
The lifetime of the access token, in milliseconds. Once
the access token has expired a new access token can be
obtained by using the provided refresh token. If no
refresh token is provided, the client will need to re-log in
to obtain a new access token. If not given, the client can
assume that the access token will not expire.
Omitted if the `inhibit_login` option is false.
x-addedInMatrixVersion: "1.3"
home_server: home_server:
type: string type: string
description: |- description: |-

Loading…
Cancel
Save