我为django rest框架编写android客户端。我使用 ModelsViewSet 与django rest框架。当我尝试用我的Android客户端创建新用户时,我收到此错误:
[08 / Jan / 2015 22:49:23]“POST / users / HTTP / 1.1”403 59
这是我的Android客户端代码:
public class Test extends Activity {
String URL = "http://192.168.0.103:8000/users/";
String result = "";
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_layout);
/*
*Make http call to the webservice
*/
RequestTask ws = new RequestTask();
ws.execute(URL);
} // end onCreate()
private class RequestTask extends AsyncTask<String, String, String>{
@Override
protected String doInBackground(String... uri) {
// TODO Auto-generated method stub
HttpClient httpClient = new DefaultHttpClient();
HttpResponse response;
String responseString = null;
HttpPost httppost = new HttpPost(uri[0]);
try{
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("username", "dinho"));
nameValuePairs.add(new BasicNameValuePair("date_of_birth", "2013-12-11"));
nameValuePairs.add(new BasicNameValuePair("gender", "Male"));
nameValuePairs.add(new BasicNameValuePair("description", "tout choco"));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
response = httpClient.execute(httppost);
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
}else{
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
}catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return responseString;
}
@Override
protected void onPostExecute(String result) {
if (result!=null) {
EditText et = (EditText)findViewById(R.id.ws_test_field);
et.setText(result);
}
}
}
}
这是我的ModelViewSet
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly, permissions.AllowAny)
请帮助我,我试着解决这个步骤,因为2天。谢谢你的帮助。
答案 0 :(得分:0)
由于您无法查看获得的响应正文,因此解决此问题的选项非常有限。当您收到403
错误时,我们知道这是身份验证或授权(权限)问题。
您似乎没有对请求执行任何身份验证,因此很可能DRF假设您正在与匿名用户合作。假设这是正确的,您很可能会遇到权限问题。
您正在使用两个权限类IsAuthenticatedOrReadOnly
和AllowAny
。因为您将AllowAny
与另一个权限类一起使用,所以它绝对没有任何效果,实际上可以毫无问题地将其删除。 IsAuthenticatedOrReadOnly
类限制匿名用户访问,使他们can only make GET
, OPTIONS
, or HEAD
requests到端点。如果您尝试执行任何其他操作(例如POST
请求),则会因403
错误而拒绝该操作,因为权限检查失败。
解决此问题的最简单方法是更改ViewSet
上的权限,以允许匿名创建用户。
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
def get_permissions(self):
# Allow anonymous user registration
if self.action == "create":
return permissions.AllowAny()
return permissions.IsAuthenticatedOrReadOnly()
为此,我们覆盖get_permissions
而不是implementing a new permission class。您可能还希望look into more complex permissions用户修改其他人的数据。
答案 1 :(得分:0)
i solve my problem by suppress permissions.IsAuthenticatedOrReadOnly in permission classes and i have add headers parameter to my android post request my correct django source code is:
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = (permissions.AllowAny,)
and i have add this to my android souce code:
my android final code souce is:
public class Test extends Activity {
String URL = "http://192.168.0.103:8000/users/";
String result = "";
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_layout);
/*
*Make http call to the webservice
*/
RequestTask ws = new RequestTask();
ws.execute(URL);
} // end onCreate()
private class RequestTask extends AsyncTask<String, String, String>{
@Override
protected String doInBackground(String... uri) {
// TODO Auto-generated method stub
HttpClient httpClient = new DefaultHttpClient();
HttpResponse response;
String responseString = null;
HttpPost httppost = new HttpPost(uri[0]);
try{
httppost.setHeader("Accept", "application/json");
httppost.setHeader("Content-type", "application/json");
JSONObject obj = new JSONObject();
obj.put("username", "abcd");
obj.put("date_of_birth", "2013-12-11");
obj.put("gender", "Male");
obj.put("description", "tout choco");
httppost.setEntity(new StringEntity(obj.toString(), "UTF-8"));
// Execute HTTP Post Request
response = httpClient.execute(httppost);
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
}else{
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
}catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return responseString;
}
@Override
protected void onPostExecute(String result) {
if (result!=null) {
EditText et = (EditText)findViewById(R.id.ws_test_field);
et.setText(result);
}
}
}
}
感谢大家的帮助!