2

私は単純な平均スタックアプリケーションを持っています。認証について学び、それを動作させようとします。平均ログインとリダイレクトの処理方法をスタック

あなたはgithubの中に完全なプログラムチェックアウトすることができます。

angular.module('chat', ['ui.router', 'chat.main', 'chat.signin', 'chat.profile']) 
.config(function($stateProvider, $urlRouterProvider, $httpProvider) { 

    $urlRouterProvider.otherwise('/'); 

    $stateProvider 
     .state('home', { 
      url: '/', 
      templateUrl: 'views/main.html', 
      controller: 'MainCtrl' 
     }) 
     .state('signin', { 
      url: '/signin', 
      templateUrl: 'views/signin.html', 
      controller: 'SigninCtrl' 
     }) 
     .state('profile', { 
      url: '/profile', 
      templateUrl: 'views/profile.html', 
      controller: 'ProfileCtrl' 
     }); 

    // the following will give angular injection error 
    /* 
    $httpProvider.interceptors.push(function($q, $state) { 
     return { 
     response: function(response) { 
      // do something on success 
      return response; 
     }, 
     responseError: function(response) { 
      if (response.status === 401) { 
      $state.go('home'); 
      } 
      return $q.reject(response); 
     } 
     }; 
    }); 
    */ 

}); 

をそして私はNodeJSが認証を処理するように機能している:私は、プロファイルのルートに(app.js)角度で次のように制限されているhttps://github.com/7seven7lst/chatterApp

を:

var express = require('express'); 
var bodyParser = require('body-parser'); 
var cookieParser = require('cookie-parser'); 
var path = require('path'); 
var session = require('express-session'); 
var passport = require('passport'); 
var LocalStrategy = require('passport-local').Strategy; 

// setup passport 
passport.use(new LocalStrategy(
    function(username, password, done){ 
    if (username !== 'test' || password !='password'){ 
     console.log("not loged in "); 
     return done(null, false); // login failed 
    } else { 
     console.log("somehow we are here"); 
     return done(null, {username: username}); 
    } 
    } 

)); 



passport.serializeUser(function(user, done){ 
    done(null, user); 
}); 
passport.deserializeUser(function(user, done){ 
    done(null, user); 
}) 

// middleware function to handle protected route 
var requireAuthentication = function(req, res, next){ 
    if (req.isAuthenticated()){ 
    next(); 
    } else { 
    console.log("401 should be sent here..."); 
    res.end(401); 
    //res.redirect('/login'); 
    } 
} 

var app = express(); 
app.use(bodyParser.json()); 
app.use(bodyParser.urlencoded({ extended: false })); // middleware to parse the form data 
app.use(express.static(__dirname + '/public')); // server static file in public folder. 
app.use('/bower_components', express.static(__dirname + '/bower_components')); 
app.use(cookieParser()); 
app.use(session({ 
    secrete: 'make this a good secret', 
    resave: false, 
    saveUninitialized: true 
})); 
app.use(passport.initialize()); 
app.use(passport.session()); 


app.get('/', function(req, res){ 
    console.log("here, homepage"); 
    res.sendFile('index.html'); 
}) 


app.post('/signin', passport.authenticate('local', { 
    successRedirect: '/profile', failureRedirect: '/login' 
}), function(req, res){ 
    res.send(req.user); 
}); 


app.get('/profile', [requireAuthentication, 
function(req, res){ 
    console.log("here, profile page"); 
    res.json(200, {username: req.session.passport.user.username}); 
}]) 

app.get('*', function(req, res){ 
    res.redirect('/'); 
}) 

app.listen(8080, function(){ 
    console.log("listening on port 8080"); 
}) 

私は私のアプリをテストし、何401はこれまで、サーバから送信されません。そして、上記の行のコメントを外してみると、角度のインターセプターは動作していないようです。 保護ルートがanuglarで動作するようにするにはどうすればよいですか?

答えて

2

リポジトリコードを見ると、signin.htmlのフォームのように、送信時にsignin関数を呼び出そうとしています。この関数は定義されていないので、要求はサーバーに送信されないため、応答はありません。

編集:

あなたMEANアプリケーションの認証を扱うときに、2つの別々の考慮事項があります。認証はサーバーとクライアントで行われます。サーバー上で

サーバー

、ルートのユーザーが認証されていない場合、クライアントは401のステータスコード応答を送信されますrequireAuthenticationミドルウェアを使用していました。

ブラウザでlocalhost:8080/profileと入力すると、サーバーから401応答が返されます。

あなたがhtml5modeを使用する指定していないため、クライアント上のクライアント

。クライアント側のルーティングは、フラグメントURL(#で始まるURLの一部)を使用して行われます。そのURLの部分はサーバーに送信されません。 localhost:8080/#/profileに要求すると、サーバーがhttp要求で取得するパスは/になります。

あなたのケースではindex.htmlファイルで応答するようにサーバー上には/ルートが設定されています。 index.htmlは、角度スクリプトをロードする要求を行い、クライアントコードを実行します。

この時点で、ui.routerはクライアント側ルーティングを処理します。ここで、クライアントでの認証チェックが必要です。状態が認証を要求することを示すためのいくつかの戦略があります。

このような方法の1つは、実際の状態の定義にタグを入れている:

$stateProvider 
    .state('home', { 
    url: '/',   // is actually /#/ 
    templateUrl: 'views/main.html', 
    controller: 'MainCtrl' 
    }) 
... 
    .state('profile', { 
    url: '/profile', // is actually /#/profile 
    templateUrl: 'views/profile.html', 
    controller: 'ProfileCtrl', 
    authRequired: true 
    }); 

その後stateChangeStartイベント用rootscopeに聞く追加実行ブロックの追加:

app.run(function($rootScope, $state, Auth) { 
    $rootScope.$on('$stateChangeStart', function(event, nextState, params) { 
    if (nextState.authRequired && !Auth.isAuthenticated()) { 
     $state.go('signin'); 
    } 
    }); 
}); 

認証サービスをはじめてサーバーラウンドトリップが必要なユーザーが認証されているかどうかを知る必要があります。 stackoverflowには、それを行う方法に関する答えがたくさんあります。


その他の部分は$httpProvider.interceptors部分です。あなたの角のクライアントから、認証が必要なルートにサーバーに要求を行う場合は、/profile/#/profileではないことを覚えておいてください。ちょうど/です)、認証されていない場合、401という応答が得られます。 authインターセプター部分は、その状況でどのように応答するかを角度クライアントに指示します。

.config(function($stateProvider, $urlRouterProvider, $httpProvider, $injector) { 

... 

    $httpProvider.interceptors.push(function($q) { 
    return { 
     responseError: function(response) { 
     if (response.status === 401) { 
      $injector.get('$state').go('signin'); 
     } 
     return $q.reject(response); 
     } 
    }; 
    }); 
}); 
関連する問題