Ваши API
Приложение может запросить токен доступа для одного из ваших API. Оно получает подписанный JWT, аудитория которого — этот API и больше никто, а ваш API проверяет его опубликованными ключами вашей среды, не обращаясь к Usher. Токен для одного API бесполезен для другого.
Укажите API
В Usher Console откройте среду, затем Приложения → Ваши API → Добавить API. Задайте название и идентификатор: адрес https://, например https://api.example.com, или URN, например urn:example:api:notes. Идентификатор — это то, что запрашивает приложение и что указано в утверждении aud токена (RFC 8707).
Затем предоставьте API приложениям, которые его вызывают: раздел API в каждом приложении. Приложение получает токены только для тех API, которые ему предоставлены, что бы оно ни запрашивало. Если убрать API, новые токены для него выдаваться не будут, а уже выданные истекут в течение нескольких минут.
Запросите токен
Приложение добавляет resource=<identifier> к запросу авторизации и к запросам токенов. Мобильные SDK делают это за вас:
let usher = UsherClient(configuration: .init(
issuer: URL(string: "https://login.example.com")!,
clientID: "…",
redirectURI: URL(string: "com.example.notes:/oauth/callback")!,
resources: ["urn:example:api:notes"]))
var request = URLRequest(url: URL(string: "https://api.example.com/notes")!)
try await usher.authorize(&request) // Authorization: Bearer <a JWT for the Notes API>val usher = Usher.client(context, UsherConfiguration(
issuer = "https://login.example.com",
clientId = "…",
redirectUri = "com.example.notes:/oauth/callback",
resources = listOf("urn:example:api:notes")))Приложение, которое вызывает два ваших API, может запросить оба сразу; тогда в аудитории токена будут указаны оба.
Проверьте токен в своем API
Проверяйте токен в каждом запросе, прежде чем доверять чему-либо в нем:
- Подпись — по ключам из
jwks_uriв документе обнаружения вашей среды. Берите алгоритм из ключа, а не из заголовка токена. issв точности совпадает с издателем вашей среды. Зафиксируйте его в конфигурации и никогда не берите из токена.audсодержит идентификатор вашего API. (С областьюopenidв нем также указан адрес userinfo вашей среды.)typв заголовке равенat+jwt, чтобы ID-токен нельзя было выдать за токен доступа.expеще не наступил. Токены доступа действуют 10 минут; SDK обновляют их за вас.
В Node.js все это делает @usher/node:
import { createVerifier } from '@usher/node'
const usher = await createVerifier({
issuer: 'https://login.example.com',
audience: 'urn:example:api:notes',
})
const claims = await usher.accessToken(bearerToken) // throws if any check failsВ ASP.NET Core:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(o =>
{
o.Authority = "https://login.example.com"; // discovery and keys come from here
o.MapInboundClaims = false;
o.TokenValidationParameters = new()
{
ValidIssuer = "https://login.example.com",
ValidAudience = "urn:example:api:notes",
ValidTypes = ["at+jwt"],
};
});Что содержит токен
| Утверждение | |
|---|---|
sub | Человек. Вместе с iss — ключ, по которому его стоит хранить. |
client_id, azp | Приложение, которое запросило токен. |
scope | Что, по согласию человека, может делать приложение. |
email, email_verified | С областью email: адрес человека и подтвердил ли Usher, что адрес принадлежит ему. |
sid | Сеанс входа человека. |
org | С областью organization: активная организация человека и его роль в ней. |
Люди, которых вы уже знаете
Если в вашем API уже есть аккаунты, созданные раньше, вы можете найти аккаунт человека, когда он впервые придет с токеном Usher: найдите его по email, только если email_verified равно true, и с этого момента храните iss и sub в его аккаунте. После этого ищите его по iss и sub, а не по e-mail: адрес может перейти к другому человеку, а субъект — никогда.