Flutter dio伪造请求头获取数据

在很多时候,后端为了安全都会有一些请求头的限制,只有请求头对了,才能正确返回数据。这虽然限制了一些人恶意请求数据,但是对于我们聪明的程序员来说,就是形同虚设。下面就以极客时间为例,讲一下通过伪造请求头,来获取极客时间首页主要数据。(不保证接口和安全措施一直可用哦)

查看极客时间的数据端口

如果你是一个前端,这套流程可能已经烂熟于心,先找出掘金的一个端口,来进行分析。

首先在浏览器端打开极客时间(我用的是chrome浏览器):https://time.geekbang.org/ ,然后按F12打开浏览器控制台,来到NetWork选项卡,再选择XHR选项卡,这时候刷新页面就会出现异步请求的数据。我们选择topList这个接口来进行查看。

拷贝地址:https://time.geekbang.org/serv/v1/column/topList

我们就以这个接口为案例,来获取它的数据。

非法的请求

注意的是,这时候我们并没有设置请求头,为的是演示我们不配置请求头时,是无法获取数据的,它会返回一个451的错误。

451:就是非法请求,你的请求不合法,服务器决绝了请求,也什么都没给我们返回。代码如下:

import 'package:flutter/material.dart';
import 'package:dio/dio.dart';


class HomePage extends StatefulWidget {
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  String showText='还没有请求数据';
  @override
  Widget build(BuildContext context) {
    return Container(
       child: Scaffold(
         appBar: AppBar(title: Text('请求远程数据'),),
         body: SingleChildScrollView(
           child: Column(
             children: <Widget>[
               RaisedButton(
                 onPressed: _jike,
                 child: Text('请求数据'),
               ),
               Text(showText)
             ],
           ),
         ),
       ),
    );
  }

  void _jike(){
    print('开始向极客时间请求数据............');
    getHttp().then((val){
      setState(() {
       showText=val['data'].toString();
      });
    });
  }

  Future getHttp()async{
    try{
      Response response;
      Dio dio = new Dio(); 
      response =await dio.get("https://time.geekbang.org/serv/v1/column/topList");
      print(response);
      return response.data;
    }catch(e){
      return print(e);
    }
  }

}

这时候我们运行,点击请求数据按钮,会返现控制台无情的输出了异常消息。

I/flutter ( 6942): DioError [DioErrorType.RESPONSE]: Http status error [451]
E/flutter ( 6942): [ERROR:flutter/shell/common/shell.cc(184)] Dart Error: Unhandled exception:

伪造请求头

新建一个文件夹,起名叫作config,然后在里边新建一个文件httpHeaders.dart,把请求头设置好,请求头可以在浏览器中轻松获得Request Headers,复制获得后需要进行改造。

const httpHeaders={
'Accept': 'application/json, text/plain, */*',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Connection': 'keep-alive',
'Content-Type': 'application/json',
'Cookie': '_ga=GA1.2.676402787.1548321037; GCID=9d149c5-11cb3b3-80ad198-04b551d; _gid=GA1.2.359074521.1550799897; _gat=1; Hm_lvt_022f847c4e3acd44d4a2481d9187f1e6=1550106367,1550115714,1550123110,1550799897; SERVERID=1fa1f330efedec1559b3abbcb6e30f50|1550799909|1550799898; Hm_lpvt_022f847c4e3acd44d4a2481d9187f1e6=1550799907',
'Host': 'time.geekbang.org',
'Origin': 'https://time.geekbang.org',
'Referer': 'https://time.geekbang.org/',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'
};

有了请求头文件后,可以引入请求头文件,并进行设置,主要代码就这两句。

import '../config/httpHeaders.dart';

dio.options.headers = httpHeaders;

完成代码如下:

import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import '../config/httpHeaders.dart';

class HomePage extends StatefulWidget {
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  String showText='还没有请求数据';
  @override
  Widget build(BuildContext context) {
    return Container(
       child: Scaffold(
         appBar: AppBar(title: Text('请求远程数据'),),
         body: SingleChildScrollView(
           child: Column(
             children: <Widget>[
               RaisedButton(
                 onPressed: _juejin,
                 child: Text('请求数据'),
               ),
               Text(showText)
             ],
           ),
         ),
       ),
    );
  }

  void _juejin(){
    print('开始向极客时间请求数据..................');
    getHttp().then((val){
      setState(() {
       showText=val['data'].toString();
      });
    });
  }

  Future getHttp()async{
    try{
      Response response;
      Dio dio = new Dio();
      dio.options.headers= httpHeaders;
      response =await dio.get("https://time.geekbang.org/serv/v1/column/topList");
      print(response);
      return response.data;
    }catch(e){
      return print(e);
    }
  }

}

现在运行程序就可以正常获取数据了。

总结: 学习了Dio中如何通过伪造请求头来获取别人接口的数据,学会了这个是非常有用的,以后我们想自己作练习Demo时就不用为后端接口而犯愁了。当然查看接口的方法比较初级,我们可以使用向Fiddler这样的专用软件来获得接口。

posted on 2019-08-01 09:47  JoeYoung  阅读(2896)  评论(1编辑  收藏  举报