0

角度アプリにアクセスコントロールを追加して困惑する問題に遭遇しています...Angular&UI-Routerによるアクセスコントロール。呼び出しスタックサイズのエラー&エクスプレス認証ルートに到達しません

フロントエンドでは、認証機能が繰り返し呼び出されています呼び出しスタックが大きすぎるために停止するまで毎回、関数内の$ http要求がerrorCallback関数をトリガーしています。予想される動作は、auth関数がui-routerの状態が変わるたびに一度起動し、ブラウザの認証レベルを示す$ rootScope値を変更することです。

まず、GET要求を行うための責任工場:

.factory ('authRequest', function ($http) { 
    return { 
     authStatus : function() { 
      $http.get('/auth', {'withCredentials' : true}).then(function successCallback(response) { 
       console.log("Successful authorization check."); 
       return response.status; 

      }, function errorCallback(response) { 
       if (response.status) { 
        console.log("Failed to authenticate."); 
        return response.status; 
       } 
       console.log("Failed to receive a response."); 
       return 'errNoResponse'; 
      }); 
     } 
    } 

}) 

その後、工場の応答処理するためのNG-コントローラ:バックエンドの一方

//Navbar controller, set to fire upon each state change and verify authorization. 
.controller('navCtrl', function ($rootScope, $state, authRequest) { 
    $rootScope.$on('$stateChangeStart', function (event, toState) { 
     console.log('authRequest value: ' + [authRequest]); 

     if (authRequest.authStatus === 202) { 
      console.log('Auth check succeeded, assigned user privileges.'); 
      $rootScope.loggedIn = true; 
      $rootScope.loggedInAdmin = false; 
      if (toState = 'users' || 'login') { 
       event.preventDefault(); 
      } 
     } else if (authRequest.authStatus === 222) { 
      console.log('Auth check succeeded, assigned admin privileges.'); 
      $rootScope.loggedIn = true; 
      $rootScope.loggedInAdmin = true; 
      if (toState = 'login') { 
       event.preventDefault(); 
      } 
     } else { 
      console.log('Auth check failed.'); 
      $rootScope.loggedIn = false; 
      $rootScope.loggedInAdmin = false; 
      event.preventDefault(); 
      $state.go('login'); 
     } 
    }); 
}) 

を、Iリクエストのいずれかで/ auth Expressルートに到達したという証拠は見られません。/authがGET要求を受け取ったときに消えるようにコンソールログを設定しましたが、コンソールに何も表示されません。他のすべてのエクスプレスルートは問題なくアクセスされています。期待される動作は、リクエストを受信し、リクエストのJWTクッキーヘッダーをデコードし、リストされているユーザー権限の種類に応じてレスポンスコードを送り返すことです。/authのエクスプレスルートは次のとおりです。

// GET /auth. Fired every time the app state changes. Verifies JWT authenticity and sends a response based on the user's privileges. 202 is an auth'd user, 222 is an auth'd admin. 401 is no token or error. 
app.get('/auth', function (req, res, next) { 
    console.log('Authorization request received.') 
    var decoded = jwt.verify(req.cookie, [JWTAuthSecret]); 
    if (decoded) { 
     if (decoded.admin === true) { 
      return res.status(222).send(res.status); 
      console.log(decoded.sub + ' is an admin, responded with code 222'); 
     } else { 
      return res.status(202).send(res.status); 
      console.log(decoded.sub + ' is not an admin, responded with code 202'); 
     } 
    } else { 
     return res.status(401).send(res.status); 
     console.log('Decode failed, responded with code 401'); 
    }; 
}); 

現在の設定では、アプリが無期限にハングしています。前述のように、各状態の変更時に大量の認証要求が生成されます。それぞれが「authRequest値:[オブジェクトオブジェクト]」を記録し、「認証チェックに失敗しました。結局、私は次のエラーを取得する:

angular.js:13550RangeError: Maximum call stack size exceeded 
    at angular.js:10225 
    at n.$broadcast (angular.js:17554) 
    at Object.transitionTo (angular-ui-router.js:3273) 
    at Object.go (angular-ui-router.js:3108) 
    at app.js:275 
    at n.$broadcast (angular.js:17552) 
    at Object.transitionTo (angular-ui-router.js:3273) 
    at Object.go (angular-ui-router.js:3108) 
    at app.js:275 
    at n.$broadcast (angular.js:17552) 

だから、フロントエンドの呼び出しの頻度に関する問題だけでなく、実際に/認証ルートに送信されたデータを取得する際に問題があったがあるように思われます。

これは私の初めてのアングルファクトリです。私の本能は私の工場での実装がうんざりだと仮定しています...しかし、私自身はそれがどうやって解決されるのか分かりませんでした。

読んでいただきありがとうございます。私はこの仕事をするために何を変えるべきかについていくつかアドバイスをいただきたいと思います。

答えて

2

私にはいくつかの問題があります。これはすべてを解決するわけではありませんが、うまくいけば狭いものを助けるでしょう。

1つは、authRequest.authStatusは関数ですが、決して呼び出すことはないということです。あなたのコントローラでは、関数を呼び出す必要があります。これはバックエンドにpingを実行する理由の一部です。

authRequest.authStatus().then(function(status) { 
    if (status === 202) { 
     //do stuff 
    } else if (status === 222) { 
     //do other stuff 
    } 
}); 

あなたの工場では、関数に何も返されていないので、そのことを確認してください。

.factory ('authRequest', function ($http) { 
    return { 
     authStatus : function() { 
      return $http.get('url').then(callbacks); 
     } 
    } 
}) 
+0

これらの変更により、フロントエンドで意図されたとおりにHTTPリクエストが発生するというトリックがありました。そこから私はいくつかの軽微なバックエンドのエラーのトラブルシューティングを行い、スムーズに動作するようになりました。正しい方向に私を指してくれてありがとう! – wingmatt

1

私が直面していたフロントエンドのトラブルに対する解決策を私に提示しました。/authへのGET要求は、正常にExpressに送信されましたが、有効な認証Cookieにもかかわらずエラーコードで応答していました。

JWTをデコードしようとすると、バックエンドのログを確認しているときに、JsonWebTokenError: jwt must be providedというエラーが表示されていました。 req.cookieは、リクエストのCookieを確認する正しい構文ではありません。req.cookiesです。

変更後、私のクッキーの出力はundefinedから[object Object]になりました。エラーはTypeError: jwtString.split is not a functionに変更されました。

the Express docsでクッキーが参照される方法を二重チェックした後、私はJWTクッキーを名前で呼んでいないことに気付きました。更新されたコードは次のとおりです。

app.get('/auth', function (req, res, next) { 
    console.log('Authorization request received.') 
    console.log ('Cookie Data: ' + req.cookies.CookieName); 
    var decoded = jwt.verify(req.cookies.CookieName, [JWTAuthSecret]); 
    if (decoded) { 
     if (decoded.admin === true) { 
      return res.status(222).send(res.status); 
      console.log(decoded.sub + ' is an admin, responded with code 222'); 
     } else { 
      return res.status(202).send(res.status); 
      console.log(decoded.sub + ' is not an admin, responded with code 202'); 
     } 
    } else { 
     return res.status(401).send(res.status); 
     console.log('Decode failed, responded with code 401'); 
    }; 
}); 

この変更とフロントエンドが変更されたため、アプリケーションの認証と承認が意図したとおりに機能しています。

関連する問題