ASP.Net WebAPI Owin authentication token in Knockout 在Knockout中使用ASP.Net WebAPI Owin身份验证令牌

10 浏览
0 Comments

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);  
    } 

看起来是很多代码.. 这是正确的做法吗?

0
0 Comments

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的问题。

希望以上解决方法对您有所帮助!

0