无法在 angular 中的休息响应中访问 c​​ookie

can't access cookies on a rest response in angular

我有一个 angular 前端和一个 webapi 后端。我已经使用 OWIN/Identity 和 JWT 令牌实现了 OAuth v2 安全性(感谢 Taiseer Joudeh 的博客)。我的负担是我们仍然有需要特定 cookie 的遗留页面。当从登录请求返回 JWT 令牌时,我已经扩充了来自 WebApi 的 Http 响应以包含该 cookie。我已验证 cookie 在响应 header.

我的问题是我无法在我的 angular 响应处理程序中看到 cookie,我会将它推送到浏览器。我已根据我在 Whosebug 中其他地方找到的建议尝试了以下各项,但到目前为止,我无法在 .js 代码中看到 cookie(替代尝试已被注释掉,但为了完整性而保留)。我还通过在我的 ValidateClientAuthenticationContext( ..) 方法。

我需要做什么才能在我的 webapi 响应中看到附加的 cookie?这是服务器或客户端的问题吗?两个?

在我的 authService.js 文件中:

var _login = function (loginData) {

    // this makes the data "form data"
    var data = "grant_type=password&client_id=ngAuthApp&username=" + loginData.userName + "&password=" + loginData.password;

    var deferred = $q.defer();

    $http.post(serviceBase + 'oauth/token', data, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } })
        .success(function (response) {

            localStorageService.set('authorizationData', { token: response.access_token, userName: loginData.userName });

            _authentication.isAuth = true;
            _authentication.userName = loginData.userName;

                console.log($cookies);

            //var xxx = $http.defaults.headers;
            //var headers = $http.response.headers;

            var ddc = $http.response.cookies;
            $cookies.DDC = ddc;

            deferred.resolve(response);

        })
        //.success(function (data, status, headers, config) {
        //    // any required additional processing here 
        //    var results = [];
        //    results.data = data;
        //    results.headers = headers();
        //    results.status = status;
        //    results.config = config;

        //    deferred.resolve(results);
        //})
        .error(function (err, status) {
            _logOut();
            deferred.reject(err);
        });

    return deferred.promise;

};

在我的自定义 OAuthProvider .cs 文件中

public 覆盖任务 ValidateClientAuthentication(OAuthValidateClientAuthenticationContext 上下文) { // 此处跳过大量代码

        context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin });
        context.OwinContext.Response.Headers.Add("Access-Control-Allow-Credentials", new[] { "true" });
        context.OwinContext.Response.Headers.Add("Access-Control-Allow-Headers", new[] { "authorization", "content-type", "set-cookie" });

        context.Validated();
        return Task.FromResult<object>(null);
    }

您的 $http 调用还应将 withCredentials 标志设置为 true 以明确允许 cookie 共享。

$http.post(url, {withCredentials: true, ...})

withCredentials 标志允许 javascript 访问用户的已验证会话。

//编辑 既然我再次阅读了你的问题,这可能不是你的问题。 withCredentials 是为了在您发出的下一个需要经过身份验证的会话的请求时将您的会话传达给服务器。从你的问题来看,你似乎想在 js 代码中验证你验证的 cookie 是否也可以通过代码访问。

根据文档 - 请参阅 here

$http.post() 方法 returns 一个 HttpPromise 未来对象。您对 .post() returns 的调用是一个承诺。根据上述参考页面上的弃用通知:

The $http legacy promise methods success and error have been deprecated. Use the standard then method instead. If $httpProvider.useLegacyPromiseExtensions is set to false then these methods will throw $http/legacy error.

所以不要使用 .success() / error(),而是使用这个:(从文档中复制)

$http.post()
.then(function successCallback(response) {
  // this callback will be called asynchronously
  // when the response is available
}, function errorCallback(response) {
  // called asynchronously if an error occurs
  // or server returns response with an error status.
});

此外,如果您还没有尝试过这个(根据 .post() 调用,它似乎没有)设置您的 responseType 属性 =14=]配置object。这会设置返回的 response 对象的 datatype。否则返回 DOM stringdefault。它可能无法修复它,但它可能是一个开始。

这可能还需要借助withCredentials属性设置。测试它们,看看效果如何。想法来自bastijn.

的建议

原来我的假设有误。我预计浏览器会忽略直接从嵌入式 js 代码通过 Web 服务发送的 cookie。但是,响应 header 在 header 中具有 "Set-Cookie" 值,并且浏览器已经将其推送到与其余 cookie 一起使用。真没想到。

我必须补充一点,这对我来说是一个非常有用的问题,因为它教会了我很多关于网络编程以及浏览器如何使用 http header 值的知识。我感谢大家的时间!

马库斯