Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >.Net核心:用离子前端验证防伪令牌

.Net核心:用离子前端验证防伪令牌
EN

Stack Overflow用户
提问于 2018-01-30 14:00:16
回答 1查看 467关注 0票数 1

我找遍了所有的地方,找到了类似的解决方案,但没有任何东西与我所做的完全相符。

我们有一个.net核心MVC网站与一个处理来自离子移动应用程序的请求,我们也正在开发。

在大多数情况下,将[ValidateAntiForgeryToken]添加到API控制器操作中是可行的。我已经完成了生成令牌、将其传递给Ionic并将其存储在请求头中以进行验证的过程。

下面是我用来获取和存储令牌的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static XSRF_TOKEN_KEY: string = "X-XSRF-TOKEN";
static XSRF_TOKEN_NAME_KEY: string = "X-XSRF-TOKEN-NAME";

constructor(){}

static getXsrfToken(http: HTTP) : {tokenName: string, token: string} {
    let tokenName: string = window.sessionStorage.getItem(ValidationManager.XSRF_TOKEN_NAME_KEY);
    let token: string = window.sessionStorage.getItem(ValidationManager.XSRF_TOKEN_KEY);
    if(!tokenName || !token){
        this.fetchXsrfToken(http);
        tokenName= window.sessionStorage.getItem(ValidationManager.XSRF_TOKEN_NAME_KEY);
        token = window.sessionStorage.getItem(ValidationManager.XSRF_TOKEN_KEY);
    }
    return {
        tokenName: tokenName,
        token: token
    };
}

private static setXsrfToken({ token, tokenName }: { token: string, tokenName: string }) {
    window.sessionStorage.setItem(ValidationManager.XSRF_TOKEN_KEY, token);
    window.sessionStorage.setItem(ValidationManager.XSRF_TOKEN_NAME_KEY, tokenName);
}

private static fetchXsrfToken(http: HTTP) {
    let token: string = window.sessionStorage.getItem(ValidationManager.XSRF_TOKEN_KEY);
    let tokenName: string = window.sessionStorage.getItem(ValidationManager.XSRF_TOKEN_NAME_KEY);

    if (!token || !tokenName) {
        let apiUrl: string = AppConfig.apiUrl + "/GetAntiforgeryToken";
        http.get(apiUrl, {}, {})
            .then(r => this.setXsrfToken(JSON.parse(r.data)))
            .catch(r => console.error("Could not fetch XSRFTOKEN", r));
    } else {
        this.setXsrfToken({ token: token, tokenName: tokenName });
    }
}

下面是我的控制器中为防伪造令牌服务的操作:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[HttpGet]
public override IActionResult GetAntiforgeryToken()
{
    var tokens = _antiforgery.GetAndStoreTokens(HttpContext);
    return new ObjectResult(new
    {
        token = tokens.RequestToken,
        tokenName = tokens.HeaderName
    });
    }

我通过从视图的关联类型记录文件调用此函数来设置http插件的标题:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
initializeHttp() {
    let token = ValidationManager.getXsrfToken(this.http);
    this.http.setHeader(token.tokenName, token.token);
    console.log("Http Initialized: ", token);
}

然后,我使用http插件提出的任何请求都会在控制器的操作中得到正确的验证:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
this.http.post(apiUrl, {}, {}).then(response => {
   that.navCtrl.setRoot(HomePage);
});

到目前为止,一切都很好。当我尝试使用XmlHttpRequest作为帖子而不是内置的http插件时,问题就出现了:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let file = {
    name: e.srcElement.files[0].name,
    file: e.srcElement.files[0],
  };

  let formData: FormData = new FormData();
  formData.append('file', file.file);

  let xhr: XMLHttpRequest = new XMLHttpRequest();
  xhr.open('POST', apiUrl, true);
  console.log("setting request header: ", tokenVal); //verify that tokenVal is correct
  xhr.setRequestHeader("X-XSRF-TOKEN", tokenVal);
  xhr.send(formData);

如果我从控制器的操作中删除[ValidateAntiForgeryToken]属性,文件就会正确发布。但是,我尝试过的任何东西都无法处理包含的属性。

我相信这个问题与由Ionic自动添加到cookie中的验证令牌有关,cookie与来自http插件的请求一起传递。但是,XMLHttpRequest并没有传递cookie (并且无法传递?)。

在过去的几天里,我读了很多关于这个问题的文章,但我承认,对我来说,这种验证仍然是个黑匣子。是否有一种方法仅使用标头中传递的令牌来验证我的操作中的请求?

我遇到这个问题的原因是我需要上传一个文件,这是我无法使用http插件完成的。有一些使用Ionic的file-transfer插件上传图片的解决方案,但是它已经被废弃了,发布说明建议使用XmlHttpRequest

其他我尝试过的事情:

  • 我已经找到了.net标准的解决方案,这些解决方案在服务器上使用System.Web.Helpers.AntiForgery进行自定义验证,但是.net核心中没有包含这个名称空间,也找不到相应的名称空间。
  • 我尝试了许多不同的方式来使用http发布文件(因为它没有验证antiForgery令牌的问题)。我所做的每一件事都会导致这个动作被击中,但是被发布的文件总是null。使用http插件上传文件的解决方案也是可以接受的。
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-01-30 14:54:48

为什么我可以花整整两天的时间来解决这个问题,但我一提出问题,就找到了答案。有时候我觉得网络上的神只是在耍我。

事实证明,本地的http插件有一个uploadFile()函数,我在其他地方从未见过这个函数。以下是解决方案的作用:

  1. 使用fileChooser插件从手机的存储中选择一个文件
  2. 使用filePath插件解析映像的本机文件系统路径。
  3. 使用http.uploadFile()而不是http.post()

这是因为如上所述,我能够正确地设置http插件头中的验证令牌以供控制器接受。

这是密码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let apiUrl: string = AppConfig.apiUrl + "/UploadImage/";
this.fileChooser.open().then(
  uri => {
    this.filePath.resolveNativePath(uri).then(resolvedPath => {
      loader.present();
      this.http.uploadFile(apiUrl,{ },{ },resolvedPath, "image")
      .then(result => {
        loader.dismiss();
        toastOptions.message = "File uploaded successfully!";
        let toast = this.toastCtrl.create(toastOptions);
        toast.present();
        let json = JSON.parse(result.data);
        this.event.imageUrl = json.imgUrl;
      })
      .catch(err => {
        console.log("error: ", err);
        loader.dismiss();
        toastOptions.message = "Error uploading file";
        let toast = this.toastCtrl.create(toastOptions);
        toast.present();
      });
    });
  }
).catch(
  e => console.log(e)
);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48531227

复制
相关文章
noip模拟-确定的位置(map + vector)
想清楚了就不难 这题还是在c程上机课的时候a掉的 还是aaa和vv的命名,本家独创 还是只会举例论证,wztcl 题目:确定的位置 描述 hzy很喜欢了解歌曲的排行榜,他每次都从XX网站获知。 由于这个网站想对这个歌曲的排行榜含蓄的告诉大家,组织了一个“猜榜大赛”。 这个网站宣布一些歌曲的信息,那些歌曲在歌曲榜上的前几名,例如: ·”qianlizhiwai” 是在榜上的前三名 ·”qianlizhiwai”,”dachengxiaoai” 是在歌曲榜的前两名 网站不会把歌曲的名次十分明确的告诉你,他就是
wenzhuan
2022/08/15
3570
机器人变身(类与对象)【期中模拟】
编写一个机器人类,包含属性有机器名、血量、伤害值、防御值、类型和等级。其中血量、伤害和防御和等级、类型相关:
叶茂林
2023/07/30
1790
利用面向对象思想,写一个名为Account的类模拟账户,模拟存取钱系统。
该类的属性和方法如下所示。 该类包括的属性:账户id,余额balance,年利率annualInterestRate; 包含的方法:各属性的set和get方法。取款方法withdraw(),存款方法deposit()
百思不得小赵
2022/12/01
5250
C/C++:string类的模拟实现
string的文档网站 string类的介绍以及一些常见问题 String是一个管理字符数组的类,要求这个字符数组结尾用 ‘\0’ 标识 涉及的问题如下: 拷贝构造和赋值重载实现 深拷贝 增删查改的相关接口 重载一些常见的运算符如:[] 、>> 、<< 等 迭代器 对于一个成员函数,什么时候该加const呢? 1 、如果是 只读函数 ,则要加 const 2 、如果是 只写函数 ,则不能加 const 3 、如果 既是可读又是可写的函数 ,则要重载两个版本的函数,即 const 版本
利刃大大
2023/04/12
3650
【C++】string类的模拟实现
1. 库里面的构造函数实现了多个版本,我们这里就实现最常用的参数为const char *的版本,为了同时支持无参的默认构造,这里就不在多写一个无参的默认构造,而是用全缺省的const char *参数来替代无参和const char *参数的两个构造函数版本。
举杯邀明月
2023/04/12
6360
【C++】string类的模拟实现
【C++】string类的模拟实现
分为无参和带参这两种构造函数。无参构造函数默认构造空字符串"",所以我们只需要给一个缺省值即可。
平凡的人1
2022/11/21
7360
【C++】string类的模拟实现
Flash如何模拟EEPROM
很多的MCU控制器不带有片上EEPROM,但是我们有时候鉴于成本的考虑又不想外扩EEPROM,所以经常用Flash来模拟EEPROM存储,但是Flash都是块擦除,所以需要考虑频繁擦除的影响,需要借鉴软件算法来综合考虑,最近经常在使用NXP的KE系片子,KE系列除过KE02带有256字节的片上EEPROM外,KE04和KE06都不带片上EEPROM,所以我们采用Flash来模拟。
用户1605515
2019/06/17
2.9K0
Flash如何模拟EEPROM
如何在 Android 模拟器中模拟 GPS 位置
可以通过 Telnet 连接到仿真器。然后你有一个模拟器控制台,可以让你输入某些数据,比如地理定位、网络等。
张云飞Vir
2021/12/06
9.8K0
如何在 Android 模拟器中模拟 GPS 位置
【游戏开发】在Lua中实现面向对象特性——模拟类、继承、多态
  Lua是一门非常强大、非常灵活的脚本语言,自它从发明以来,无数的游戏使用了Lua作为开发语言。但是作为一款脚本语言,Lua也有着自己的不足,那就是它本身并没有提供面向对象的特性,而游戏开发是一项庞大复杂的工程,如果没有面向对象功能势必会为开发带来一定的不便。不过幸好Lua中有table这样强大的数据结构,利用它再结合元表(metatable),我们便可以很方便地在Lua中模拟出类、继承和多态等面向对象编程具有的特性。
马三小伙儿
2018/09/12
3.1K0
[C++]日期类计算器的模拟实现
彼此分享给大家的目的一样,希望所有正在学技术被技术所困的友友们,在艰难的时候看到这句话能披荆斩棘,勇往直前!
IT编程爱好者
2023/04/12
6300
[C++]日期类计算器的模拟实现
Mastercam 实体模拟中如何加入夹具一起模拟?
当图档载入设定好素材时,可在上面选单选择“机器”-模拟右下会有一个箭头”模拟选项”,点选可设定夹具。
lrglu
2022/05/16
1.5K0
Mastercam 实体模拟中如何加入夹具一起模拟?
如何模拟弱网环境?
运维过程中,最复杂的问题,莫过于网络的问题,而网络问题最烦的就是无法复现,这篇介绍一个强大的网络模拟工具Netem
李俊鹏
2020/06/11
2.9K0
如何模拟弱网环境?
用LinkedList类实现&nbsp;模拟堆栈…
public static void main(String [] args)
明明如月学长
2021/08/27
4020
接口vs抽象类的区别?如何用普通的类模拟抽象类和接口?
在面向对象编程中,抽象类和接口是两个经常被用到的语法概念,是面向对象四大特性,以及很多设计模式、设计思想、设计原则编程实现的基础。比如,我们可以使用接口来实现面向对象的抽象特性、多态特性和基于接口而非实现的设计原则,使用抽象类来实现面向对象的继承特性和模板设计模式等等。
码农架构
2021/01/19
1.2K0
[PyUserInput]模拟鼠标和键盘模拟
http://www.lfd.uci.edu/~gohlke/pythonlibs/
周小董
2019/03/25
3.3K0
Python手写模拟单向链表对象,栈对象和树
单向链表: class error(Exception): def __init__(self,msg): super(error,self).__init__() self.msg=msg def __str__(self): return self.msg class Node: def __init__(self,ele): self.ele=ele self.next=None class
步履不停凡
2019/09/11
6460
【C++】list迭代器的深度剖析及模拟实现(感受类封装,类和对象的思想)
1. 从迭代器的上层角度来看,vector和list的迭代器的使用没有差别,迭代器的begin和end返回的是左闭右开的区间位置[ begin(),end() )。
举杯邀明月
2023/04/12
1.1K0
【C++】list迭代器的深度剖析及模拟实现(感受类封装,类和对象的思想)
银行排队模拟(离散事件模拟)
这里用的是链队列,所以要有一个节点结构体和一个队列类,其次节点的数据域里面存放的是用户结构体类型,所以还要定义一个用户结构体类型
大忽悠爱学习
2021/03/12
1.6K0
银行排队模拟(离散事件模拟)
JMeter如何模拟不同的网络速度
在大多数情况下,移动设备用户通过其蜂窝运营商网络访问互联网。覆盖范围将根据其位置而有所不同,这意味着连接速度将有所不同。确保您的网站或应用程序能够完全处理移动设备和平板电脑,即使它们具有不同的互联网连接速度,也至关重要。
FunTester
2020/04/08
1.1K0
如何在phpunit中mock(模拟)一个单例类
Mock简介 当我们对A类进行单元测试时,A类可能依赖了B类,为了减少依赖,方便A类方法的测试,我们可以模拟一个B类,简单规定其各方法的返回值(而非真正实现具体逻辑)。Phpunit中提供了一套模拟类的api,简单使用如下:
跑马溜溜的球
2020/12/07
3.1K0

相似问题

jMock模拟类与接口

11

使用jMock注入模拟对象

15

使用带有具体类的模拟对象的JMock

11

属性设置为模拟对象jmock。

20

仙人掌与模拟对象(jMock,简易模拟)

23
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文