本文更应该叫做Android如何模拟浏览器访问Django服务器后台。

环境为:

Android通过HttpClient访问服务器,从Django中获取json数据,解析显示在UI界面上。

问题为:

1.需要登录才可以访问json数据,否则会提示权限不够

登录,也就是把用户名和密码放在请求的参数中呗,但是问题是其中会包含一个csrftoken个东西,问题就不好玩了。每次访问登录界面,都会由服务器生成一个csrftoken,放在浏览器的cookie中,登录动作中,服务器会校验cookie中的csrftoken,同时验证用户名和密码,如果验证通过,则将sessionid和csrftoken再次返回给浏览器,设置在cookie中,访问json中的数据时,会同时检验sessionid和csrftoken,那问题就简单了,可以分成这么几步在做:

1.第一次get请求登录页,得到csrftoken

2.设置用户名,密码,cookie中的csrftoken,(其实还包括更用户名密码类似的csrfmiddlewaretoken,next参数),post请求验证,得到sessionid

3.访问json请求路径,其中请求头中设置csrftoken和sessionid,可以获得请求的数据

好了,可以写代码了:

1.定义变量

String url = "http://ipaddress:8004/api-auth/login/?next=/";//第一次get请求url
String url2 = "http://ipaddress:8004/api-auth/login/";//第二次登录验证url
DefaultHttpClient httpClient; public static String sessionID = "";
public static String scrftoken = ""; private HttpResponse mHttpResponse = null;
String htmlText;//返回的结果 Context context;

2.第一次请求,得到csrftoken

httpClient = new DefaultHttpClient();

HttpResponse response = httpClient.execute(new HttpGet(new URI(url1)));

//这里通过cooki获得,其实也可以在网页中解析csrfmiddlewaretoken获得,值是一样的

CookieStore cookieStore = httpClient.getCookieStore();

List<Cookie> cookies = cookieStore.getCookies();

String csrftoken = null;

for (Cookie cookie : cookies) {

    if (cookie.getName().equals("csrftoken")) {

        csrftoken = cookie.getValue();

    }

}

Log.i("get csrftoken", csrftoken);

3.第二次请求得到sessionid

HttpPost post = new HttpPost(new URI(url2));
List<NameValuePair> paramList = new ArrayList<NameValuePair>();
// 设置登陆信息
BasicNameValuePair csrfmiddlewaretoken2 = new BasicNameValuePair("csrfmiddlewaretoken", csrftoken);
//如果通过验证,接下来的路径,在未登录情况下访问数据,提示没有权限时
//在不同界面登录这个值可能不同,不过关系不大,这里忽略,设置成默认的/
BasicNameValuePair next = new BasicNameValuePair("next", "/");
BasicNameValuePair username = new BasicNameValuePair("username", "renyuzhuo");
BasicNameValuePair password = new BasicNameValuePair("password", "renyuzhuo");
//这个值没用
BasicNameValuePair login = new BasicNameValuePair("submit", "Log in");
// 设置发送数据
paramList.add(csrfmiddlewaretoken2);
paramList.add(next);
paramList.add(username);
paramList.add(password);
paramList.add(login); post.setEntity(new UrlEncodedFormEntity(paramList, HTTP.UTF_8));
//这句话是关键,在请求头中设置csrftoken,也有设置成X-CRFSToken的,这里不做测试了
//需要看Django
post.setHeader(new BasicHeader("csrftoken", csrftoken)); httpClient.setCookieStore(cookieStore);
mHttpResponse = httpClient.execute(post);
if (mHttpResponse.getStatusLine().getStatusCode() == 200) {
htmlText = EntityUtils.toString(mHttpResponse.getEntity(), "utf-8");
Message message = new Message();
message.what = 0;
message.obj = htmlText;
Log.i("html", htmlText); CookieStore cookieStore2 = httpClient.getCookieStore();
List<Cookie> cookies2 = cookieStore2.getCookies();
for (Cookie cookie : cookies2) {
Log.i("cookie::", cookie.getName() + " " + cookie.getValue());
//这里重复设置了csrftoken,没什么必要,写成token=csrftoken就可以了
        if (cookie.getName().equals("csrftoken")) {
csrftoken = cookie.getValue();
}
        //获取sessionid
if (cookie.getName().equals("sessionid")) {
sessionID = cookie.getValue();
}
} }

4.访问json数据:

//设置json数据的url0
HttpGet get = new HttpGet(new URI(URLS.xxxx));
get.setHeader(new BasicHeader("csrftoken", csrftoken));
get.setHeader(new BasicHeader("sessionid", sessionID));
HttpResponse response = httpClient.execute(get);
Log.i("code::", response.getStatusLine().getStatusCode() + "");
if (response.getStatusLine().getStatusCode() == 200) {
htmlText = EntityUtils.toString(response.getEntity(), "utf-8");
Log.i("html", htmlText);
} Message message = new Message();
message.what = 1;
mHandler.sendMessage(message);

常见的403错误往往就是请求头设置出错,也就是加红的部分

5.获取了json数据,接下来的操作就不在本文包含的范围内了。

附核心源码:http://files.cnblogs.com/files/renyuzhuo/DjangoLogin.zip

知其所以然:

csrftoken是什么:

Cross-site request forgery,跨站请求伪造,就是其他网站伪造请求,达到攻击的目的,你说说我这上面的代码方式是不是就是一个伪造请求呢,也算是一种攻击吧,不过我的目的仅仅是因为服务器没有给我预留接口,我就只能这样了。如果是一个循环,必定是一个不会造成什么严重后果的攻击。

Django REST Framework是什么:

基于Django的REST框架,是一个轻量级的库,可以很容易构建WEB API,被设计成模块化,易用于自定义的体系结构,基于Django的基础类视图。python,Django

Django是什么:

官网宣传标语:Django makes it easier to build better Web apps more quickly and with less code.

官网的解释:Django is a high-level Python Web framework that encourages rapid development and clean, pragmatic design. Built by experienced developers, it takes care of much of the hassle of Web development, so you can focus on writing your app without needing to reinvent the wheel. It’s free and open source.

 

下面的链接对你可能有帮助:

403错误:http://stackoverflow.com/a/17283820/440489

CSRF介绍:http://drops.wooyun.org/papers/155

Django REST Framework官网:http://www.django-rest-framework.org/

Django REST Framework学习——Android使用REST方法访问Diango的更多相关文章

  1. Django Rest Framework(认证、权限、限制访问频率)

    阅读原文Django Rest Framework(认证.权限.限制访问频率) django_rest_framework doc django_redis cache doc

  2. Django restful Framework 之Requests and Response 方法

    前言: 本章主要介绍REST framework 内置的必要的功能. Request objects Response objects Status codes Wrapping API views ...

  3. Django REST Framework 学习笔记

    前言: 基于一些不错的RESTful开发组件,可以快速的开发出不错的RESTful API,但如果不了解开发规范的.健壮的RESTful API的基本面,即便优秀的RESTful开发组件摆在面前,也无 ...

  4. 【转】Android SDK Samples,学习Android的好方法

    转载地址:http://blog.csdn.net/rowland001/article/details/50886288 从今天开始呢,我要开始学习Google家自己出的Android代码示例,总觉 ...

  5. PyQt(Python+Qt)学习随笔:invisibleRootItem方法访问QTreeWidget树型部件的隐形根节点

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 我们知道在数据结构上来说,任何树都是有根节点的,但我们在QTreeWidget对象中并没有看到界面上 ...

  6. django rest framework restful 规范

    内容回顾: . django请求生命周期 -> 执行遵循wsgi协议的模块(socket服务端) -> 中间件(路由匹配) -> 视图函数(业务处理:ORM.模板渲染) -> ...

  7. Django REST framework完全入门

    Django REST framework 一个强大灵活的Django工具包,提供了便捷的 REST API 开发框架 我们用传统的django也可以实现REST风格的api,但是顶不住Django ...

  8. Django REST framework JWT学习

    1.JWT学习 在用户注册或登录后,我们想记录用户的登录状态,或者为用户创建身份认证的凭证.我们不再使用Session认证机制,而使用Json Web Token认证机制. Json web toke ...

  9. Android FrameWork学习(二)Android系统源码调试

    通过上一篇 Android FrameWork学习(一)Android 7.0系统源码下载\编译 我们了解了如何进行系统源码的下载和编译工作. 为了更进一步地学习跟研究 Android 系统源码,今天 ...

随机推荐

  1. boost

    参考博客 http://www.cnblogs.com/lidabo/p/3805487.html http://www.cppblog.com/Robertxiao/archive/2013/01/ ...

  2. C++ 完美破解九宫格(数独)游戏

    看到CSDN上有位大神用C#写了一个破解数独的程序(点击打开链接),不过我对C#也不懂,比较喜欢C++,就用标准C++也写了一个,希望各位喜欢.三纯程序,纯控制台程序,纯各人爱好,纯算法程序,无win ...

  3. Google Guava的splitter用法

    google的guava库是个很不错的工具库,这次来学习其spliiter的用法,它是一个专门用来 分隔字符串的工具类,其中有四种用法,分别来小结 1 基本用法: String str = " ...

  4. Python新手学习基础之循环结构——For语句

    for语句 在Python里,循环语句除了while语句,还有for语句. 通常我们用for循环来遍历(按约定的顺序,对每个点进行访问,且只做一次访问)有序列的内容,比如列表和字符串(列表内容我们会在 ...

  5. 创建C#DLL

    1. 创建classlibrary 2.编写一个COM接口和一个COM类 [Guid("DBE0E8C4-1C61-41f3-B6A4-4E2F353D3D05")] public ...

  6. ARM 汇编器对C的扩展

    __swi void ledtest();    //:声明 edtest 是个软中断. __asm  内嵌汇编          //:通常在C程序里面需要嵌入汇编代码,这是就可以用__asm关键字 ...

  7. windows下adb+flash_image刷机

    刷机是常事,总要把刷机包放在卡上,然后关机三键一起按到recovery再刷,觉得不爽,麻烦,所以研究出了adb调用flash_image刷system分区,全部脚本windows脚本执行,点点鼠标就o ...

  8. Activity 模版样式简介

    1:对话框样式. <activity android:theme="@android:style/Theme.Dialog"> 2:透明样式. <activity ...

  9. Codeforces 533B Work Group

    http://codeforces.com/problemset/problem/533/B 题目大意: 每个人有一个直接的领导,1是总裁,现在要找一个最大的集合,每个领导领导的人的数量都是偶数,问最 ...

  10. CentOS下Qt窗口透明效果失效,成黑色背景的问题

    一.问题 Linux系统下Qt窗口的透明效果成了黑色,但同样的代码在windows机子上有透明效果,主要是修改系统的配置,仅在centos6.3及其以上版本实验过.其他系统可以相应配置. 二.问题运行 ...