У меня проблемы с разработкой приложения для Android, которое я хочу аутентифицировать с помощью Django REST framework для безопасного доступа к информации. Мне успешно выдан токен REST, но IsAuthenticated
остается ложным для всех моих представлений.
В Django у меня есть представление на основе классов, которое отвечает, если оба authentication.TokenAuthentication
permissions.IsAuthenticated
действительны:
class TestAuthView(APIView):
authentication_classes = (authentication.TokenAuthentication,)
permission_classes = (permissions.IsAuthenticated,)
def get(self, request, format=None):
return GetRestData()
В Android я получаю токен, отправив мои uname и passwd на URL-адрес по умолчанию: /rest-auth/login/
, который отвечает токеном: {"key":"c03c1238ab99d91301d34567bda9d417d2b48c0c"}
public static String getResponseFromHttpUrl(String... params) throws IOException {
ArrayList<AbstractMap.SimpleEntry<String,String>> paramssss = new ArrayList<>();
paramssss.add(new AbstractMap.SimpleEntry<>("username", "root"));
paramssss.add(new AbstractMap.SimpleEntry<>("password", "mypass"));
URL url = new URL(params[0]);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(3000);
urlConnection.setConnectTimeout(3000);
urlConnection.setRequestMethod("POST");
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
OutputStream os = urlConnection.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write(getQuery(paramssss));
writer.flush();
writer.close();
os.close();
urlConnection.connect();
try {
InputStream in = urlConnection.getInputStream();
Scanner scanner = new Scanner(in);
scanner.useDelimiter("\\A");
boolean hasInput = scanner.hasNext();
if (hasInput) {
return scanner.next(); //eg. {"key":"c03c1238ab99d91301d34567bda9d417d2b48c0c"}
} else {
return null;
}
} finally {
urlConnection.disconnect();
}
}
Затем я сохраняю токен, а затем использую его для запроса некоторых данных:
@Override
protected String doInBackground(String... sUrl) {
try {
URL url = new URL(sUrl[0]);
URLConnection urlConnection = url.openConnection();
String authToken = "c03c1238ab99d91301d34567bda9d417d2b48c0c"; //just use a constant string for now..
urlConnection.addRequestProperty("Authorization", "Token " + authToken);
urlConnection.addRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
urlConnection.connect();
...
process the response
...
Просматривая журналы Django, я вижу, что вход в систему выполнен успешно, но запрос GET завершается неудачно с HTTP_401_UNAUTHORIZED
:
[08 / Oct / 2019 22:18:53] "POST / rest-auth / login / HTTP / 1.1" 200 50
[08 / Oct / 2019 22:18:53] «GET / update / HTTP / 1.1» 401 58
Когда я изменяю access_classes на AllowAny
:
class TestAuthView(APIView):
authentication_classes = (authentication.TokenAuthentication,)
permission_classes = (permissions.AllowAny,) //Changed this!!!
def get(self, request, format=None):
return GetRestData()
Ответ содержит ожидаемые данные RESTи все успешно:
[08 / Oct / 2019 22:24:57] "POST / rest-auth / login / HTTP / 1.1" 200 50
[08 / Oct/ 2019 22:25:02] "GET / update / HTTP / 1.1" 200 19451876
Я не понимаю, как правильно аутентифицировать свое приложение для Android, чтобы IsAuthenticated
не всегда было ложным?
В настоящее время я отправляю имя пользователя и пароль для /rest-auth/login/
и мне выдан токен отдыха. Но должен ли я также войти в систему где-нибудь еще, чтобы получить токен CSRF и использовать его?
Я не знаком с необходимостью permissions.IsAuthenticated
, и действительно ли он подходит для приложений Android? Я имею в виду, я просто оставляю разрешение как AllowAny
для не браузерных приложений Android? Я чувствую, что это плохая идея ..?
Я подключился к этому в течение нескольких дней и буду рад любой помощи!