Таблица пояснений кодов ошибок Azure auth2
https://learn.microsoft.com/en-us/azure/active-directory/develop/reference-error-codes
сообщить об ошибке
AADSTS9002327: Tokens issued for the 'Single-Page Application' client-type may only be redeemed via cross-origin requests
предыстория истории
Мне нужно позвонить в office365 (AAD) через Azure, 刷新令牌
чтобы получить новый токен и обновить токен. В контейнере на стороне браузера это не проблема (поскольку это спа-приложение и оно использует поток авторизации PKCE), но в подприложении, представленном mricro-приложением микроинтерфейса в качестве основы контейнера в электрон, источник не может быть успешно добавлен в заголовок запроса.
анализировать
Тут может быть два предположения
: 1. Перехватчик запросов Electron перезаписывает заголовок запроса, что предотвращает запись источника суб-приложения.
2. Из-за механизма безопасности браузера источник не будет отображаться при перекрестном происхождении.
решать
Я electron的请求拦截器
обработал , задав определенный тег заголовка запроса vv-origin
, electron请求拦截器
перехватив этот тип запроса в , и вручную добавив origin
атрибуты, значение которых указано как vv-origin
переданное значение.
Код подпрограммы:
const url = `https://login.microsoftonline.com/${
off_tenant}/oauth2/v2.0/token`;
const params = {
client_id: off_clientId,
scope: off_scopes.join(' '),
refresh_token: refreshToken,
grant_type: 'refresh_token',
};
axios
.post(url, params, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'vv-origin': 'http://localhost', // 自定义了一个vv-origin头,方便electron下的微前端基座应用拦截请求头,如果写成origin可能会被重写掉导致拦截不到
},
})
.then((res) => {
console.log('success===>', res);
if (res && res.data) {
const data = res.data;
// 获得刷新后的token和refreshToken
const opts = {
serviceId,
refreshToken: data.refresh_token,
accessToken: data.access_token,
expiresIn: data.expires_in,
email,
};
console.log('使用刷新令牌从office获取新的访问令牌', data, opts);
updateBindEmailInfo(opts);
}
});
Код электронного приложения на рабочем столе для перехвата запроса:
interceptorsRequest() {
session.defaultSession.webRequest.onBeforeSendHeaders(
async (detail: Electron.OnBeforeSendHeadersListenerDetails, callback) => {
this.requestMap[detail.id] = pick(detail, [
'id',
'url',
'method',
'resourceType',
'timestamp',
'requestHeaders'
]);
if (detail.requestHeaders['vv-origin']) {
callback({
requestHeaders: {
...detail.requestHeaders,
origin: detail.requestHeaders['vv-origin']
}
});
}
callback({
responseHeaders: headers });
});
}