如下,我在Orchard Core框架中添加了一个API的模块,并且定义了对应的权限才可以调用,那么我们现在考虑的就是要怎么去调用它。

首先,我们用Fiddler查看下我们正常的登录的http报文,直接在浏览器输入路径例如: http://192.168.0.225:8082/admin ,会直接跳转到登录页,路径是:http://192.168.0.225:8082/Login?ReturnUrl=%2Fadmin

admin被添加到一个ReturnUrl的参数后面,输入账号密码然后回车登录到后台。这样一个登录操作就完成了,我们再看看Fiddler的报文:

在login的时候发送了一个__RequestVerificationToken参数,并且在返回的时候set了一个cookie,这个cookie包含了这个登录用户的身份信息等等,

所以当我们关闭浏览器但没有logout退出,再次进入admin后台时,不需要再次登录操作,就是因为在这个时候记录了cookie。

那么__RequestVerificationToken参数又是怎么来的呢?我们知道这整个过程,每一个http报文都是紧接着上一条报文的结果,

我们看看上一个报文,它返回了一个Document,我们在这个Document找到了这个元素 name="__RequestVerificationToken"

这个元素的value就是__RequestVerificationToken参数的值。

再看看这个Document,里面有一个Form,意思就是Form里的内容会submit到Form对应的action中。

我一开始以为,了解了这个过程,我们就可以用ajax模拟登录得到cookie了,但是用如下代码,返回的总是400错误,浏览器拒绝了请求。

$.ajax({
url: 'http://192.168.0.225:8082/admin',
type: 'get',
cache: false,
success: function (data) {
var objval = $(data).find("[name='__RequestVerificationToken']").val();
var url = $(data).find(".form-horizontal").attr("action");
$.ajax({
url: "http://192.168.0.225:8082" +url,
type: 'post',
cache: false,
async: false,
data: {
'UserName': 'admin',
'Password': 'XXXXXXXXX',
'__RequestVerificationToken': objval,
'RememberMe': false
},
success: function (data, status, xhr) {
alert("ok");
console.log(xhr.getAllResponseHeaders());
}
});
}
});

这里猜测,估计是因为浏览器的安全机制,拦截了我的ajax

那么我就换C#模拟http请求,可以得到我要的API返回的结果,代码如下:

//发送请求
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri("http://192.168.0.225:8082");
try
{
//在没有登录之前,不管写什么路径,都会跳到login页面,而所写的路径会自动添加到returnurl这个参数后
//登录之后就会跳转到这个页面
//这一步是为了拿到__RequestVerificationToken
var cliPost = client.GetAsync("/warehouseapi/admin/index");
cliPost.Wait();
var result = cliPost.Result;
string resultContent = result.Content.ReadAsStringAsync().Result;
//返回了一个Document对象,用NSoup解析,NSoup可以用像jQuery那样的选择器选择元素
var htmlDoc = NSoup.NSoupClient.Parse(resultContent);
var __RequestVerificationToken = htmlDoc.Select("[name=__RequestVerificationToken]").Val();
var actionPath = htmlDoc.Select(".form-horizontal").Attr("action");
//准备Post的参数
var content = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("UserName", "admin"),
new KeyValuePair<string, string>("Password", "ZXXXXXXXX@"),
new KeyValuePair<string, string>("RememberMe", "false"),
new KeyValuePair<string, string>("__RequestVerificationToken", __RequestVerificationToken), });
try
{
//发送请求
//登录
var cliPost1 = client.PostAsync(actionPath, content);
cliPost1.Wait();
var result1 = cliPost1.Result;
string resultContent1 = result.Content.ReadAsStringAsync().Result; //向API发送请求
var cliGet = client.GetAsync("/warehouseapi/admin/index");
cliGet.Wait();
var resultGet = cliGet.Result;
string resultContent2 = resultGet.Content.ReadAsStringAsync().Result;
Console.WriteLine(DateTime.Now + "======" + resultContent2);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Console.Read();

  

补充:上面是get请求方式,如果是post请求的时候,由于框架有ValidateAntiForgeryToken这个的验证,所以每次请求都要带上一个__RequestVerificationToken参数。

ValidateAntiForgeryToken的用途是防止CSRF(跨网站请求伪造),这个具体的可以百度了解。

总之每次post请求一个api路径都要带上__RequestVerificationToken参数,而__RequestVerificationToken参数是基于上一次请求返回的html页面中[name="__RequestVerificationToken"]的hidden标签的值,这个值每次是不一样的。

post请求的示例如下:

//发送请求
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri("http://192.168.0.225:8082");
try
{
//在没有登录之前,不管写什么路径,都会跳到login页面,而所写的路径会自动添加到returnurl这个参数后
//登录之后就会跳转到这个页面
//这一步是为了拿到__RequestVerificationToken
var cliPost = client.GetAsync("/Login?ReturnUrl=%2Fadmin");
cliPost.Wait();
var result = cliPost.Result;
string resultContent = result.Content.ReadAsStringAsync().Result;
//返回了一个Document对象,用NSoup解析,NSoup可以用像jQuery那样的选择器选择元素
var htmlDoc = NSoup.NSoupClient.Parse(resultContent);
var __RequestVerificationToken = htmlDoc.Select("[name=__RequestVerificationToken]").Val();
var actionPath = htmlDoc.Select(".form-horizontal").Attr("action");
//准备Post的参数 用户名、密码错误会跳回登录页
var content = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("UserName", "wXXXXXi"),
new KeyValuePair<string, string>("Password", "XXXXXXXX21"),
new KeyValuePair<string, string>("RememberMe", "false"),
new KeyValuePair<string, string>("__RequestVerificationToken", __RequestVerificationToken),
});
try
{
//发送请求
//登录
var cliPost1 = client.PostAsync(actionPath, content);
cliPost1.Wait();
var result1 = cliPost1.Result;
string resultContent1 = result1.Content.ReadAsStringAsync().Result; //返回了一个Document对象,用NSoup解析,NSoup可以用像jQuery那样的选择器选择元素
var htmlDoc1 = NSoup.NSoupClient.Parse(resultContent1);
var __RequestVerificationToken1 = htmlDoc1.Select("[name=__RequestVerificationToken]").Val();
var actionPath1 = htmlDoc1.Select(".form-horizontal").Attr("action"); //var cliGet = client.GetAsync("/warehouseapi/admin/index");
//cliGet.Wait();
//var rs = cliGet.Result;
//string rscontent = rs.Content.ReadAsStringAsync().Result; //向API发送请求
DeliveryRecords drc = new DeliveryRecords()
{
CustCode = "001",
LogisticCode = "SUER001",
Express = "速尔",
OutNo = "abc01",
Assistant = "何助理",
DanQty = "1",
JianQty = "13",
SendDate = "2018-11-22"
};
string rcJsonStr = JsonConvert.SerializeObject(drc);
var rcContent = new FormUrlEncodedContent(new[] {
new KeyValuePair<string, string>("__RequestVerificationToken", __RequestVerificationToken1),
new KeyValuePair<string, string>("rcJson", rcJsonStr)
});
var cliRcPost = client.PostAsync("/warehouseapi/admin/InsertDeliRecoAsync", rcContent);
cliRcPost.Wait();
var rs = cliRcPost.Result;
var rsStr = rs.Content.ReadAsStringAsync().Result;
Console.WriteLine(rsStr);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Console.Read();

  

Orchard Core 增加了一个API模块,要怎么调用的更多相关文章

  1. 在使用HttpClient做客户端调用一个API时 模拟并发调用时发生“死锁"?

    平时还是比较喜欢看书的..但有时候遇到问题还是经常感到脑袋一蒙..智商果然是硬伤.. 同事发现了个问题,代码如下: class Program { static void Main(string[] ...

  2. Orchard Core 自定义权限配置

    在我们为Orchard Core配置了一个新的Module之后,我们要考虑的是谁可以访问这个Module,那么这里就涉及到了一个权限的配置.如下图,添加了自定义的权限: Orchard Core源码: ...

  3. Orchard Core 简介

    Orchard Core 是基于ASP.NET Core 对Orchard CMS的 二次开发. Orchard Core由两部分组成: Orchard Core Framework: 一个基于ASP ...

  4. Orchard Core Framework:ASP.NET Core 模块化,多租户框架

    Orchard Core Framework:ASP.NET Core 模块化,多租户框架 上一篇编写Orchard Core一分钟搭建ASP.NET Core CMS ,介绍ASP.NET Core ...

  5. 发布基于Orchard Core的友浩达科技官网

    2018.9.25 日深圳市友浩达科技有限公司发布基于Orchard Core开发的官网 http://www.weyhd.com/. 本篇文章为你介绍如何基于Orchard Core开发一个公司网站 ...

  6. Orchard Core 使用工作流处理审批和创建内容项

    译自:http://www.ideliverable.com/blog/orchard-core-workflows-walkthrough-content-approval 转载请注明出处, 原文地 ...

  7. 创建一个Orchard Core CMS 应用程序

    开始使用Orchard Core作为NuGet软件包 在本文中,我们将看到使用Orchard Core提供的NuGet包创建CMS Web应用程序是多么容易. 你可以在这里找到Chris Payne写 ...

  8. 002.Create a web API with ASP.NET Core MVC and Visual Studio for Windows -- 【在windows上用vs与asp.net core mvc 创建一个 web api 程序】

    Create a web API with ASP.NET Core MVC and Visual Studio for Windows 在windows上用vs与asp.net core mvc 创 ...

  9. ASP.NET Core 3.0 一个 jwt 的轻量角色/用户、单个API控制的授权认证库

    目录 说明 一.定义角色.API.用户 二.添加自定义事件 三.注入授权服务和中间件 三.如何设置API的授权 四.添加登录颁发 Token 五.部分说明 六.验证 说明 ASP.NET Core 3 ...

随机推荐

  1. Java编程的逻辑 (79) - 方便的CompletionService

    ​本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...

  2. 教你一招:[转载]使用 Easy Sysprep v4 封装 Windows 7 精品

    (一) 安装与备份系统 1. 安装 Windows 7 先使用第三方分区工具(DiskGenius分区)在虚拟机中分区,然后将封装的母盘文件安装写入指定的安装盘,写入完成后重启系统开始部署. 2. 进 ...

  3. JS封装动画框架,网易轮播图,旋转轮播图

    JS封装动画框架,网易轮播图,旋转轮播图 1. JS封装运动框架 // 多个属性运动框架 添加回调函数 function animate(obj,json,fn) { clearInterval(ob ...

  4. 第三百九十六节,Django+Xadmin打造上线标准的在线教育平台—其他插件使用说,自定义列表页上传插件

    第三百九十六节,Django+Xadmin打造上线标准的在线教育平台—其他插件使用说,自定义列表页上传插件 设置后台列表页面字段统计 在当前APP里的adminx.py文件里的数据表管理器里设置 ag ...

  5. [原创] Xinput_1.3.DLL / MSVCR100.DLL文件缺失解决办法

    缺少如上文件,最简单粗暴的办法就是360卫士,找人工服务搜索方案,一键修复,屡试不爽!

  6. 【中间件安全】Apache 安全加固规范

    1. 适用情况 适用于使用Apahce进行部署的Web网站. 2. 技能要求 熟悉Apache配置文件,能够利用Apache进行建站,并能针对站点使用Apache进行安全加固. 3. 前置条件 1. ...

  7. Android进阶:ListView性能优化异步加载图片 使滑动效果流畅

    ListView 是一种可以显示一系列项目并能进行滚动显示的 View,每一行的Item可能包含复杂的结构,可能会从网络上获取icon等的一些图标信息,就现在的网络速度要想保持ListView运行的很 ...

  8. babel 7 简单升级指南

    babel 7 babel 7 发布两天了,试着对当前项目更新了下,仅此记录分享 主要改动参考 官方博客 官方升级指南 主要升级内容 不再支持放弃维护的 node 版本 0.10.0.12.4.5 使 ...

  9. DBeaver连接达梦数据库

    1.连接类型选择ODBC. 2.编辑驱动设置: 1)Class Name:dm.jdbc.driver.DmDriver 2)URL Template:jdbc:dm://{dbserver}/{da ...

  10. mysql的安装和配置

    1.mydql的安装 重装wind7系统之后,mysql软件自动卸载了.现在学习需要使用mysql,还是要安装mysql.我首先通过下载安装包的方式安装,按照教程,但是出现缺失.dll文件,我下载安装 ...