【问题标题】:Android HttpPost 403 errorAndroid HttpPost 403 错误
【发布时间】:2015-03-07 06:53:39
【问题描述】:

我为 django rest 框架编写 android 客户端。我将 ModelsViewSet 与 django rest 框架一起使用。当我尝试使用我的 android 客户端创建新用户时,我收到此错误:

[08/Jan/2015 22:49:23]“POST /users/HTTP/1.1”403 59

这是我的安卓客户端代码:

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);

                }
        }


    }

}

这是我的模型视图集

class UserViewSet(viewsets.ModelViewSet):

    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly, permissions.AllowAny)

请帮助我,我从 2 天开始就尝试解决此步骤。感谢您的帮助。

【问题讨论】:

  • @aschattney 你认为这是 csrf_token 的问题吗?
  • 有什么方法可以获得正在返回的 403 响应的正文?这就是它会告诉你问题所在的地方。
  • @KevinBrown 没有任何方法可以获得 403 响应的正文,但我现在是身份验证或权限错误,但我不知道如何解决它
  • 是的,我认为您需要提供令牌作为参数或完全禁用此中间件..

标签: android python django django-rest-framework


【解决方案1】:

由于您无法查看收到的回复正文,因此您解决此问题的选项非常有限。当您收到 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 给修改其他数据的用户。

【讨论】:

  • 这很奇怪,但是这个错误是由权限引起的。AllowAny()
【解决方案2】:
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);

                }
        }


    }

}

感谢大家的帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-05
    • 1970-01-01
    • 2013-10-10
    • 1970-01-01
    • 1970-01-01
    • 2013-06-09
    • 1970-01-01
    • 2011-09-10
    相关资源
    最近更新 更多