google oauth2 redirect_uri с несколькими параметрами

Как добавить параметры в Google oauth2 redirect_uri?

Именно так redirect_uri=http://www.example.com/redirect.html?a=b,

b из a=b является случайным

Кто-нибудь может помочь?

6 ответов

Решение
  1. Вы не можете ничего добавить к URI перенаправления, URI перенаправления является постоянным, как установлено в настройках приложения Oauth. например: http://www.example.com/redirect.html

  2. Чтобы передать несколько параметров в ваш URI перенаправления, сохраните их в stateПараметр перед вызовом Oauth url, URL после авторизации отправит те же параметры в ваш URI перенаправления, что иstate=THE_STATE_PARAMETERS

Так что для вашего случая сделайте это:

/ 1. создайте строку параметров json ->

{ "a" : "b" , "c" : 1 }

/ 2. сделать base64UrlEncode, чтобы сделать его URL безопасным ->

stateString = base64UrlEncode('{ "a" : "b" , "c" : 1 }');

Это пример PHP base64UrlEncoding & decoding ( http://en.wikipedia.org/wiki/Base64):

function base64UrlEncode($inputStr)
{
    return strtr(base64_encode($inputStr), '+/=', '-_,');
}

function base64UrlDecode($inputStr)
{
    return base64_decode(strtr($inputStr, '-_,', '+/='));
}

Так что теперь состояние будет что-то вроде: stateString -> asawerwerwfgsg,

Передайте это состояние в URL авторизации OAuth:

https://accounts.google.com/o/oauth2/auth?
  client_id=21302922996.apps.googleusercontent.com&
  redirect_uri=https://www.example.com/back&
  scope=https://www.google.com/m8/feeds/&
  response_type=token&
  state=asdafwswdwefwsdg,

Для потока на стороне сервера он поставляется вместе с токеном: http://www.example.com/redirect.html?token=sdfwerwqerqwer&state=asdafwswdwefwsdg,

Для потока на стороне клиента он будет добавлен в хеш вместе с токеном доступа: http://www.example.com/redirect.html#access_token=portyefghsdfgdfgsdgd&state=asdafwswdwefwsdg,

Получите состояние, base64UrlDecode его, json_decode его, и у вас есть ваши данные.

Узнайте больше о Google OAuth 2 здесь:

http://code.google.com/apis/accounts/docs/OAuth2.html

Поскольку принятый ответ раскрывает фактические данные и неправильно использует stateвместо того, чтобы придерживаться одноразового номера для защиты от CSRF, я постараюсь показать правильный метод. Вместо того, чтобы передавать (разоблачать чтение) данные, их следует хранить локально. Гидратируйте его перед запросом и повторно гидратируйте после подтвержденного запроса. "Проверено" здесь означает, что одноразовое состояние запроса и ответа совпадает.

Вам нужно какое-то временное хранилище на стороне клиента. Например, для SPA или обычных веб-сайтов сохраняйте его в состоянии или используйте локальное хранилище браузера, сеанс (или подписанный файл cookie). Для мобильных приложений они должны использовать память или любое другое локальное хранилище.

Перед отправкой запроса сгенерируйте одноразовый номер (см. Ниже), который будет использоваться как stateпараметр для запроса. Сохраните одноразовый номер вместе с настраиваемым состоянием (например, json) в локальном хранилище.

Например, одноразовый номер может быть ih4f984hf и пользовательское состояние {"role": "customer"}. Затем вы можете сохранить данные для регидратации для этого запроса следующим образом:

"ih4f984hf": {
  "role": "customer"
}

Затем используйте только одноразовый номер в качестве значения дляstateпараметр запроса. (Если вы абсолютно хотите объединить одноразовый номер и данные вstate value обязательно зашифруйте его и помните, что длина значения ограничена!)

При получении ответа вы получаете значение stateпараметр назад. Найдите его, и если оно соответствует значению в локальном хранилище, вы можете обработать данные, используя сохраненное состояние. Если одноразовые значения не совпадают, запрос потенциально исходит от злоумышленника и не должен обрабатываться.

Генерация одноразового номера

Помните, что природа одноразового номера состоит в том, что он используется только один раз и должен быть непредсказуемым! Непредсказуемый здесь означает идеально случайный, но практически псевдослучайный - это нормально, если энтропия достаточно высока - в веб-приложениях вы можете проверить Web API Crypto, который поддерживается довольно хорошо.

Для дальнейшего чтения это может быть полезно:

Если вы находитесь в.NET, вы можете сохранить параметры в сеансе

HttpContext.Current.Session[{varname}]

и перенаправить на страницу авторизации без параметров

Response.Redirect(your_uri_approved_with_no_querystring_parameters);

В Javascript (Node) вы можете установить для свойства объект пар ключ-значение.

                 const oAuth2Client = await new google.auth.OAuth2(
                clientId: <clientId>,
                clientSecret: <clientSecret>,
                redirectUrl: <redirectUrl>,
            );

            return await oAuth2Client.generateAuthUrl({
                access_type: "offline",
                scope: <scopes>,
                state: JSON.stringify({ a: "y", b: "z" }),
            });

По завершении авторизации Google он возвращает state, codeи т. д. из ulr,

const params = JSON.parse(state); // { a: "y", b: "z" }

Вы можете перенаправить параметр с помощью URL, как показано ниже,

Когда вы получите ответ от Google, чем вы можете передать параметр с помощью URL,

Смотрите ниже код PHP для того же,

if (isset($_GET['code'])) {
   $client->authenticate();
   $_SESSION['token'] = $client->getAccessToken();
   $redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
   header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL) . '?r=page/view');

}

В приведенном выше примере r=page/view является параметром, на который я хочу получить ответ с параметром

Вы можете использовать параметр состояния для хранения данных, используя nonce в структуре, закодированной в base64.

Если вам необходимо передать данные в параметр состояния. Постройтес nonce внутри параметра состояния. Вот так:

      {
  "role": "customer",
  "nonce": "ih4f984hf",
}

Как только вы закодируете ~структуру~ в формате Base64, вы сможете убедиться, что она не была подделана. В том числе и случайность.

Предупреждение. С помощью бизнес-логики вам необходимо убедиться, что состояние данных, которое вы пытаетесь поддерживать на протяжении всего запроса, считается общедоступной информацией. Ничто не защищает эти данные от декодирования злоумышленником.

Например, если данные просто представляют цветовую тему и пользователь возвращается в это состояние по возвращении, можно отправить безобидное значение. Это зависит от ваших требований.

Другие вопросы по тегам