Javascript 身份验证-$http';调用s.then()成功回调而不是错误回调

Javascript 身份验证-$http';调用s.then()成功回调而不是错误回调,javascript,angularjs,authentication,jwt,angular-http-interceptors,Javascript,Angularjs,Authentication,Jwt,Angular Http Interceptors,这可能是因为误解了如何在MEAN stack应用程序中最好地进行身份验证,或者我不了解promises和$http的.then()方法的工作原理,但每当我尝试使用不正确的凭据对后端节点服务器进行身份验证时,它都会调用$http的成功回调。然后()方法,而不是错误回调。以下是我的设置: 我正在使用jsonwebtoken和expressjwt包、AngularJS拦截器添加令牌以请求并检查401响应者的状态、设置/删除jwt等的令牌服务,以及处理登录、注销等的用户服务 通过调试,下面是发生的情况:

这可能是因为误解了如何在MEAN stack应用程序中最好地进行身份验证,或者我不了解promises和$http的
.then()
方法的工作原理,但每当我尝试使用不正确的凭据对后端节点服务器进行身份验证时,它都会调用$http的
成功回调。然后()
方法,而不是错误回调。以下是我的设置:

我正在使用
jsonwebtoken
expressjwt
包、AngularJS拦截器添加令牌以请求并检查401响应者的状态、设置/删除jwt等的令牌服务,以及处理登录、注销等的用户服务

通过调试,下面是发生的情况:

  • 发送登录请求
  • 服务器捕获请求,查找指定的用户,但在数据库中找不到他们。返回带有JSON对象的401错误,包括错误消息等
  • HttpInterceptor启用
    responseError
    方法,正确地看到它是一个状态401,删除任何可能的现有令牌,重定向到
    /login
    屏幕,并
    返回
    s
    $q.reject(response)
  • UserService.login()
    正确使用错误回调并执行
    返回响应
  • 问题-我的login.js
    .login()方法中的成功回调将运行,而不是第二个错误回调。我有一种感觉,这与中讨论的内容有关,但我的专业知识在这里有其局限性,我不太明白我接下来应该做什么来告诉链中的下一个回调,前一个回调有错误
  • 以下是我的设置:

    快递: authrouts.js 从调试来看,当我使用不正确的凭据登录时,它正确地点击了
    res.status(401).send(…)
    行,所以这部分似乎没有问题

    角度: app.js(包括HttpInterceptor) userService.js login.js(问题似乎在这里显现) 最后一部分,
    UserService.login(user).then(function(response){$location.path(“/todo”);
    是正在运行并试图将用户重定向到todo项列表的行,而我希望它运行
    console.log(“出现问题:+response”);

    就像我上面所说的,我感觉这与链接承诺有关,并且错误是如何通过链接的一部分处理的,而不是通过链接冒泡。我不确定是否需要像我上面提到的网站那样添加
    .catch()
    块。即使这是答案,我也不完全确定如何编写它

    如果我有更好的方法来组织这项活动,我当然也愿意接受建议。我必须把这项活动教给一班学生,并希望确保我教的是好的实践


    提前感谢您的帮助!

    您是否尝试在
    then()
    调用的错误情况下使用
    $q.reject

    例如


    相关文档:

    仔细查看代码的这一部分:

    this.login = function (user) {
        return $http.post("http://localhost:8080/auth/login", user).then(function (response) {
            if (response.data.success) TokenService.setToken(response.data.token);
            return response;
        }, function (response) {
            return response;
        })
    }
    
    在这里,您提供了错误回调,返回值传递给承诺链中的下一个回调。造成混乱的原因是,如果希望错误进一步传播,您仍然需要从回调返回被拒绝的抛出承诺。否则,这实际上意味着您已从错误中恢复评估和流程中的下一步将是成功。这就是你现在拥有的

    在您的情况下,您可以完全删除错误回调

    return $http.post("http://localhost:8080/auth/login", user).then(function (response) {
        if (response.data.success) TokenService.setToken(response.data.token);
        return response;
    });
    
    …或确保您返回失败的承诺

    return $http.post("http://localhost:8080/auth/login", user).then(function (response) {
        if (response.data.success) TokenService.setToken(response.data.token);
        return response;
    }, function (response) {
        return $q.reject(response);
    });
    
    …或投掷:

    return $http.post("http://localhost:8080/auth/login", user).then(function (response) {
        if (response.data.success) TokenService.setToken(response.data.token);
        return response;
    }, function (response) {
        throw new Error(response);
    });
    

    您在
    UserService
    中正确处理了错误,因此当您进入
    login.js
    页面时,它会认为UserService的任何失败都是正确处理的承诺。如果您删除
    $http
    请求中的错误处理部分,它将正常工作expect@tykowale那很有魅力。非常感谢!我还尝试添加了一个
    $q.reject(response)
    ,效果也不错,现在我对$q有了更好的理解。谢谢!我知道这将是一个简单的解决方法,这帮助我更好地理解了承诺链和$q的工作原理!
    // remember to add $q to deps
    
    this.login = function (user) {
        return $http.post("http://localhost:8080/auth/login", user).then(function (response) {
            if (response.data.success) TokenService.setToken(response.data.token);
            return response;
        }, function (response) {
            $q.reject(response);
        })
    };
    
    this.login = function (user) {
        return $http.post("http://localhost:8080/auth/login", user).then(function (response) {
            if (response.data.success) TokenService.setToken(response.data.token);
            return response;
        }, function (response) {
            return response;
        })
    }
    
    return $http.post("http://localhost:8080/auth/login", user).then(function (response) {
        if (response.data.success) TokenService.setToken(response.data.token);
        return response;
    });
    
    return $http.post("http://localhost:8080/auth/login", user).then(function (response) {
        if (response.data.success) TokenService.setToken(response.data.token);
        return response;
    }, function (response) {
        return $q.reject(response);
    });
    
    return $http.post("http://localhost:8080/auth/login", user).then(function (response) {
        if (response.data.success) TokenService.setToken(response.data.token);
        return response;
    }, function (response) {
        throw new Error(response);
    });