Redirect_uri несоответствие в fetch и gapi - PullRequest
0 голосов
/ 16 января 2019

работает над подключением пользователей к Google, и мы пытаемся получить их доступ и обновить токены из API Google, и у нас возникает проблема с обменом OAuth2-кодом на токены. Оба набора кода имеют одинаковую ошибку.

Я инициализирую клиента gapi и заполняю необходимую информацию следующим образом:

gapi.load('client:auth2', _ => {
        gapi.client.init({
            'apiKey': 'omitted for security',
            clientId: 'omitted for security',
            'scope': 'https://www.googleapis.com/auth/drive',
            'discoveryDocs': ['https://www.googleapis.com/discovery/v1/apis/drive/v3/rest']    
        }).then(_ => {
            gapi.auth2.getAuthInstance().grantOfflineAccess().then(resp => {
                if(resp.code){
                    gapi.client.request({
                        path: 'https://www.googleapis.com/oauth2/v4/token',
                        method: 'post',
                        params: {code: resp.code},
                        body: {
                            code: resp.code,
                            client_id: opts.clientId,
                            client_secret: 'omitted for security',
                            grant_type: 'authorization_code',
                            redirect_uri: 'omitted for security',
                            access_type: 'offline'
                        },
                    }).then((onfulfill, onreject, context) => {
                        console.log('fulfilled', onfulfill);
                        console.log('rejected: ', onreject);
                        console.log('context', context);
                    }).catch(err => console.error(err.body));
                }
            });

        });
    });

То, что я пытаюсь сделать в .then(), - это вызвать конечную точку токена, чтобы обменять код в ответе на токен обновления и доступа для хранения в моем бэкэнде и локальном хранилище пользователя.

Я получаю ответ об ошибке из обеих версий кода. (лучше, более надежный код предоставляется здесь.)

{"error": "redirect_uri_mismatch", "error_description": "Bad Запрос "}

У меня также есть внутренняя настройка, спрятанная как последнее средство, которая принимает код от gapi.auth2.getAuthInstance().grantOfflineAccess(), вызывает конечную точку токена и возвращает access_token и refresh_token клиенту.

Этот код похож, но не совсем. вместо использования библиотеки API Google, я использовал fetch, и она работает нормально. (Fetch и XHR на внешнем интерфейсе имеют те же проблемы, что и функция gapi.client.request ....)

const gConfig = require('./basic.json');
const scopes = ['https://www.googleapis.com/auth/drive'];

const { client_id, client_secret, redirect_uris } = gConfig.web;
const authClient = new google.auth.OAuth2(client_id, client_secret, redirect_uris[0]);

app.post('/', (req, res) => {
    const { code } = req.body;
    console.log('Received Code From Request: ', code);

    let data = { code , client_id, client_secret,redirect_uri: redirect_uris[0], grant_type: 'refresh_token'};

    let encodedParams = Object.keys(data).map(k => encodeURIComponent(k) + '=' + encodeURIComponent(data[k])).join('&');


    fetch(
        `https://www.googleapis.com/oauth2/v4/token?code=${code}`,
        { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: encodedParams }
    ).then((res) => {
        console.log('called the api with fetch');
        console.dir(res.json());
    });

    authClient.getToken(code, (err, token) => {
        if (err) {
            console.error(err);
            res.status(500).json(err);
        }
        // console.dir(token);
        console.log('TOKEN: =>', token);
        res.json(token);
    });
});

Есть ли кто-нибудь, кто сделал это на переднем конце успешно?

1 Ответ

0 голосов
/ 16 января 2019

Вы не можете получить токен обновления в браузере. Ваш пример кода будет работать только на сервере. Чтобы сделать oauth на клиенте, вы должны запросить «токен» вместо «код».

...