Android HttpPost 403错误

时间:2015-01-09 01:03:17

标签: android python django django-rest-framework

我为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天。谢谢你的帮助。

2 个答案:

答案 0 :(得分:0)

由于您无法查看获得的响应正文,因此解决此问题的选项非常有限。当您收到403错误时,我们知道这是身份验证或授权(权限)问题。

您似乎没有对请求执行任何身份验证,因此很可能DRF假设您正在与匿名用户合作。假设这是正确的,您很可能会遇到权限问题。

您正在使用两个权限类IsAuthenticatedOrReadOnlyAllowAny。因为您将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);

                }
        }


    }

}

感谢大家的帮助!