пятница, 8 ноября 2019 г.

Немного об OAuth 2.0

Столкнулся опять с REST сервисами и авторизацией с использованием протокола OAuth 2.0. Целый Authorization Framework, не хухры мухры вам. Документация на 75-и страницах.

Вся эта петрушка создаётся в основном для работы в веб-среде и когда надо работать с сервисами в обычных приложениях, то у меня лично возникают вопросы (иногда бОли). В основном от того, что в документации нет примеров нормальных и функции охватывают только веб применение.

Например, музыкальная платформа SoundCloud.

Для платформы есть так называемые SDK на JavaScript, Python и Ruby. Это официально поддерживаемые обёртки API системы.

А если я хочу написать приложение на Java или C#?
Помогает чтение документации, но это так утомительно бывает. Ладно если система распространённая и к ней есть большой интерес, тогда есть шанс, что есть уже готовые решения. Хуже когда система плохо документирована и малоизвестна.

В общем, всё это дело наживное. В основном всё сводится к получению токена у сервиса и его использование в запросах. Главное его получить. Чтобы его получить в SoundCloud используется /connect Вернее, сначала выдаётся код, а затем он подаётся на вход команде /oauth2/token, которая возвращает токен. /connect рассчитан на использование на веб-странице, т.к. предполагает переход на сайт, где будет производиться ввод имени и пароля пользователя. Нам такой вариант не подходит.

В документации SoundCloud, в описании /oauth2/token прописаны следующие параметры:
client_id
client_secret
redirect_uri
grant_type
code

Приводится пример с авторизационным кодом, который выдаётся системой при вызове /connect
В спецификации протокола OAuth grant_type может быть 4-х видов (authorization_code, refresh_token, password, client_credentials), но пример только для одного - это авторизационный код.

Самое интересное, что для приложения нужно использовать тип password, но в запрос добавляется два параметра, которые не описаны в документации - это username и password
Возможно это элементарные вещи для знающих протокол OAuth, но для новичков эти вещи непростые.

Немного Java:
public boolean initByNameAndPassword(String login, String password) {
 boolean pass = true;

 try {
     HttpURLConnection http = (HttpURLConnection) new URL(API_POINT + "oauth2/token").openConnection();
     http.setRequestMethod("POST");

     String data = new String();
     data += URLEncoder.encode("client_id", "UTF-8") + "=" + URLEncoder.encode(clientId, "UTF-8");
     data += "&" + URLEncoder.encode("client_secret", "UTF-8") + "=" + URLEncoder.encode(clientSecret, "UTF-8");
     data += "&" + URLEncoder.encode("username", "UTF-8") + "=" + URLEncoder.encode(login, "UTF-8");
     data += "&" + URLEncoder.encode("password", "UTF-8") + "=" + URLEncoder.encode(password, "UTF-8");
     data += "&" + URLEncoder.encode("scope", "UTF-8") + "=" + URLEncoder.encode("", "UTF-8");
     data += "&" + URLEncoder.encode("grant_type", "UTF-8") + "=" + URLEncoder.encode("password", "UTF-8");

     http.setRequestProperty("Content-length", "" + data.length());
     http.setDoOutput(true);
     http.setUseCaches(false);

     OutputStreamWriter wr = new OutputStreamWriter(http.getOutputStream());
     wr.write(data);
     wr.flush();
     wr.close();

     int count = http.getContentLength();

     System.out.println("initByNameAndPassword, длина контента: " + count);

     BufferedReader in = new BufferedReader(new InputStreamReader(http.getInputStream()));
     StringBuilder retStr = new StringBuilder();
     String decodedString;

     while ((decodedString = in.readLine()) != null) {
  retStr.append("Прочитана строка: " + decodedString);
     }

     System.out.println("Строка на выходе: " + retStr);

     JsonElement je = JSWork.createJson(retStr.toString());
     Gson gson = new Gson();
     token = gson.fromJson(je, SCToken.class);

     in.close();

     http.disconnect();
 } catch (IOException ioEx) {
     ioEx.printStackTrace();
     pass = false;
 }

 return pass;
    }

API_POINT - "https://api.soundcloud.com/"
Данные о токене в виде JSON. Для десериализации в класс SCToken используется библиотека GSON. Токен сохраняется в закрытое поле token, которое используется в запросах.

Такие дела. Удачи!




Комментариев нет:

Отправить комментарий

Определение параметров CHS (Cylinder, Head, Sector) карт CF с помощью утилиты IDEINFO

 Столкнулся с проблемкой подключения карт CF к материнской плате LTC-SL REV-B и WD386SX-LPX. В БИОС этих плат нет автоопределения накопителе...