ASP.Net WebAPI Owin authentication token in Knockout 在Knockout中使用ASP.Net WebAPI Owin身份验证令牌
ASP.Net WebAPI Owin authentication token in Knockout 在Knockout中使用ASP.Net WebAPI Owin身份验证令牌
我正在尝试创建一个演示项目,使用.Net ASP.Net WebAPI和KnockoutJs作为前端。我已经创建了监听/token post的控制器方法,并验证用户并返回一个token。这是通过Knockout View Model的Ajax Post完成的。
这段代码是有效的。然而,当我从webApi收到200(成功)后,我会重定向到一个带有[Authorize]修饰的控制器方法,然后遇到401-未授权的问题。
Login() { var data = { username : this.login.emailAddress(), password : this.login.password(), RememberMe: this.login.rememberMe(), grant_type: "password" } return $.ajax({ type: "POST", data: data, dataType: "json", url: "/token", contentType: "application/json" }).done((reply) => { window.location.href = "/Home/AnotherThing"; }); }
我认为问题是,我从我的/token(登录)调用中得到了一个响应,但对它什么也没做。我不确定该怎么处理token。我愚蠢地以为OAuth会以某种方式将token放入我的头部,它们会以神奇的方式存在那里。我错了。
所以,我一直在寻找一个例子,我能找到的最好的例子是这里
但这意味着我将在每个视图模型上重复很多代码。
提取:
function ViewModel() { var self = this; var tokenKey = 'accessToken'; var RefTokenKey = 'refreshToken'; self.result = ko.observable(); self.user = ko.observable(); self.token = ko.observable(); self.refreshToken = ko.observable(); function showError(jqXHR) { self.result(jqXHR.status + ': ' + jqXHR.statusText); } self.callApi = function () { self.result(''); var token = sessionStorage.getItem(tokenKey); var headers = {}; if (token) { headers.Authorization = 'Bearer ' + token; } $.ajax({ type: 'GET', url: '/api/values', headers: headers }).done(function (data) { self.result(data); }).fail(showError); } self.callToken = function () { self.result(''); var loginData = { grant_type: 'password', username: self.loginEmail(), password: self.loginPassword() }; $.ajax({ type: 'POST', url: '/Token', data: loginData }).done(function (data) { self.user(data.userName); // Cache the access token in session storage. sessionStorage.setItem(tokenKey, data.access_token); var tkn = sessionStorage.getItem(tokenKey); $("#tknKey").val(tkn); }).fail(showError); } } var app = new ViewModel(); ko.applyBindings(app);
这似乎是我缺少的一部分:
sessionStorage.setItem(tokenKey, data.access_token); var tkn = sessionStorage.getItem(tokenKey); $("#tknKey").val(tkn);
我需要每个视图模型都有代码去sessionStorage,然后获取token吗?
所以,这段代码:
var token = sessionStorage.getItem(tokenKey); var headers = {}; if (token) { headers.Authorization = 'Bearer ' + token; } $.ajax({ type: 'GET', url: '/api/values', headers: headers }).done(function (data) { self.result(data); }).fail(showError); }
看起来是很多代码.. 这是正确的做法吗?
ASP.Net WebAPI Owin身份验证令牌在Knockout中的应用问题及解决方法
问题:在使用Knockout进行开发时,如何在每个HTTP请求中附加身份验证令牌?
解决方法:可以通过将身份验证令牌附加到每个HTTP请求中来解决此问题。假设您正在使用jQuery,可以利用`beforeSend`配置参数。首先,需要提取一个可重用的方法,代码如下:
function onBeforeSend(xhr, settings) { var token = sessionStorage.getItem(tokenKey); if (token) { xhr.setRequestHeader('Authorization', 'Bearer ' + token ); } }
然后,只需将该方法附加到每个需要令牌的`$.ajax`调用中,代码如下:
$.ajax({ type: 'GET', url: '/api/values', headers: headers, beforeSend: onBeforeSend }).done(function (data) { self.result(data); }).fail(showError);
需要注意的是,`onBeforeSend`函数需要在ajax调用中可访问(我不是Knockout专家,不知道它是否具有诸如服务之类的结构,但如果没有,您可以为其添加命名空间,避免将其设置为全局函数,但代码组织方式由您决定)。
通过这种方式,您只需要在需要身份验证的请求中添加`beforeSend: onBeforeSend`,就可以避免不必要的代码重复。
另外,对于IDE不识别`headers.Authorization = 'Bearer ' + token;`的问题,在这个例子中,`headers`只是一个JS对象,而且是匿名对象。JavaScript是动态的,您可以随意操作。而且,通过使用`xhr.setRequestHeader()`方法,您不需要那行代码。建议先尝试是否有效,然后再考虑IDE的问题。
希望以上解决方法对您有所帮助!