繁体   English   中英

Knockout中的ASP.Net WebAPI Owin身份验证令牌

[英]ASP.Net WebAPI Owin authentication token in Knockout

我正在尝试创建一个使用.Net ASP.Net WebAPI和KnockoutJs作为前端的演示项目。 我创建了监听/ 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(登录)调用得到了回复,但是没有做任何事情。 我不知道如何处理令牌。 我愚蠢地认为OAuth会以某种方式将令牌放入我的标题中,并且它们会神奇地存在。 我错了。

所以,我一直在寻找一个例子,然后我能找到最好的就是这里

但这意味着我将在每个视图模型上有很多重复的代码

提取:

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,并获取令牌?

所以这:

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

这似乎是很多代码..这是正确的方法吗?

好的,您可以做的是将持有者令牌附加到您的每个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调用来访问(我不是一个淘汰的人,所以我不知道它是否有任何构造,如服务,但如果没有,你可以命名它,例如,以避免使它成为一个全局功能,但您的代码组织由您决定)。

这样,您只需将beforeSend: onBeforeSend位添加到需要auth的每个请求中,这样可以避免不必要的代码重复。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM