我在开发要通过Django REST框架进行身份验证以安全访问信息的Android应用程序时遇到了麻烦。我正在成功发放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 发布到默认网址/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
当我将Permissions_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
不会始终为False?
目前,我向/rest-auth/login/
提交了用户名和密码,并获得了休息令牌。但是我也必须在其他地方登录以获得CSRF令牌并也使用它吗?
我对permissions.IsAuthenticated
的需求并不熟悉,它是否甚至适用于Android应用程序?我的意思是我是否将非浏览器Android应用的权限保留为AllowAny
?我觉得这是个坏主意。
我已经为此花了几天时间,非常感谢您的帮助!