2016-10-28 9 views
1

パスポートのローカル戦略を使用して私の安らかなAPIの認証を実装する際に混乱の問題に直面しています。認証に問題があります

注: 私はindex.jsですべてをやっているときに認証がうまくいっています。しかし、より良いコード分離のためにクラスで使用したいと思います。

class AuthenticateController { 
    constructor(router, passport) { 
     this.router = router; 
     this.registerRoutes(); 
     this.passport = passport; 
    } 

    registerRoutes() { 
     this.router.post('/login/:username/:password', this.login.bind(this)); 
     //this.router.get('/logout', this.logout.bind(this)); 
     this.router.get('/content', this.content.bind(this)); 
    } 

    login(req, res) { 
     this.passport.authenticate("local-login", { failureRedirect: "/login"}), 
      res.redirect("/content"); 
    } 

    content(req, res) { 
     console.log(req.user); 
     if (req.isAuthenticated()) { 
      res.send("Congratulations! you've successfully logged in.") 
     } else { 
      res.sendStatus(401); 
     } 
    } 
    isLoggedIn(req, res, next) { 
    console.log(req.user); 
    if (req.isAuthenticated()) 
     return next(); 

    res.sendStatus(401); 
} 
} 

module.exports = AuthenticateController; 

コントローラは完全に私のindex.jsからパラメータとして設定されたルータとパスポートを取得します。

は、私はこれは私のコントローラクラスであるpassport.jsモジュール

// config/passport.js 

// load all the things we need 
var LocalStrategy = require('passport-local').Strategy; 
// load up the user model 
var mysql = require('mysql'); 
var dbconfig = require('./database'); 
var connection = mysql.createConnection(dbconfig.connection); 

module.exports = function(passport) { 

// passport needs ability to serialize and unserialize users out of session 
    passport.serializeUser(function (user, done) { 
     //console.log("SER"); 
     console.log(user), 
     done(null, user); 
    }); 
    passport.deserializeUser(function (user, done) { 
     console.log("XXXX"); 
     console.log(user); 
     connection.query("SELECT * FROM users WHERE name = ? ",user.name, function(err, rows){ 
      console.log("DER"); 
      console.log(rows); 
      done(err, rows[0]); 
     }); 
    }); 

// passport local strategy for local-login, local refers to this app 
    passport.use('local-login', new LocalStrategy(
     function (username, password, done) { 
      console.log("hhh"); 
      console.log(username); 
      connection.query("SELECT * FROM users WHERE name = ? ",username, function(err, rows){ 
       console.log(rows); 
       return done(err, rows[0]); 
      }); 
     }) 
    ); 

    // route middleware to ensure user is logged in 
    function isLoggedIn(req, res, next) { 
     if (req.isAuthenticated()) 
      return next(); 

     res.sendStatus(401); 
    } 
}; 

を持っています。 一般

認証を動作していない何働いているとどのような

//index.js

var express = require('express') 
    , cors = require('cors') 
    , app = express() 
    , passport = require('passport') 
    , morgan = require('morgan'); 

require('./config/passport')(passport); // pass passport for configuration 

var bodyParser = require('body-parser'); 
app.use(bodyParser.json()); 
app.use(require('express-session')({secret: 'vidyapathaisalwaysrunning', 
    resave: true, 
    saveUninitialized: true })); 

app.use(passport.initialize()); 
app.use(passport.session()); 
app.use(cors()); 

var apiRouter = express.Router(); 
app.use('/api', apiRouter); 
// 
var apiV1 = express.Router(); 
apiRouter.use('/v1', apiV1); 

var authenticateApiV1 = express.Router(); 
apiV1.use('/auth', authenticateApiV1); 

var AuthenticateController = require('./controllers/authenticate'); 
var ac = new AuthenticateController(authenticateApiV1, passport); //pass in our fully configured passport 

//If I call this /login instead of the /auth/login/ in the Controller Class it works! 
//app.post("/login", 
// passport.authenticate("local-login", { failureRedirect: "/login"}), 
// function (req, res) { 
//  res.redirect("/content"); 
// }); 

が働いています。投稿されたindex.jsには、app.post("/login", ...が表示されます。私がこれを呼び出すと認証に成功し、の制限付きコンテンツに到達しようとすると、/ auth/content/req.userに値があり、私は正常にreq.isAuthenticated()に電話することができます。制限されたコンテンツに到達しようとしたとき

しかし、私は/auth/login/username/passwordreq.userから認証を使用する場合は、未定義です。 私はエラーがなく、応答は/auth/login/username/password/ HTTPコード301 - '/ redirecting to/contentです。

I持っている現在、全く分からないノード/速達/パスポートのトピックにはかなり新しいものを - 私がここで間違っていると - 私..

ホープ誰かがアイデアを持っています。あなたが私を助けるために他に何か必要な場合は、コメントに記入して、必要なものすべてを提供するために最善を尽くします。

おかげ

EDIT:

私は最近ログイン機能でreq.userを読み込もうとしましたが、そこでも、私はそれはいくつかの非同期問題になることができると思います

login(req, res) { 
     this.passport.authenticate("local-login", { failureRedirect: "/login"}), 
      console.log(req.user) //undefined 
      res.redirect("/content"); 
    } 

未定義で、私はいくつかのコールバック関数を使用する必要がありますが、私はこれを私の中に適用する方法を知らない。login()

EDIT 2:

もう1つの問題はisLoggedIn()リクエストの統合です。

私が行う場合は、この:それは未定義でisLoggedIn()結果で401 - Unauthorized

console.log(req.user);になり

registerRoutes() { 
       this.router.get('/', this.isLoggedIn, this.getUsers.bind(this)); 
       this.router.get('/:id', this.getSingleUser.bind(this)); 
      } 

しかし、isLoggedIn()を呼び出さずに最初のルートを呼び出し、console.log(req.user);を実行すると、そのユーザーオブジェクトが存在します。

答えて

1

パスポート認証とコールバックの正しい使い方

function(req, res, next){ passport.authenticate('local-login', function(err, user, info){ if(err) return logger.log('error', err); if(user) req.login(user, function(err){ if(err) return next(err); return res.json({'success': true}); }); if(!user) return res.json({'error':true, 'message': info.message, 'type': info.type}); })(req, res, next);
}

がreq.loginの使用を()に注意してください明示秒でユーザーを設定するには:ローカル戦略のために以下のようにすることができ退会。

+0

お返事ありがとうございます。あなたの解決策は私がタイムアウトに踏み込んだ唯一の解決策でした、そして、それはうまくいくようです!おかげで –

+0

私は助けることができてうれしい。 – divsingh

1

私が奇妙なことを発見している唯一のことは、ルート宣言が異なることです。 index.jsで、ルートは単にあなたのクライアントがサーバにログイン証明書を提出しているどのように

app.post("/login", ... 

として宣言されている間

this.router.post('/login/:username/:password', ... 

AuthenticateControllerルートで

は次のように宣言されていますか? the tutorialのような形式の場合は、パスパラメータとして:username:passwordが宣言されていますが、パスポートでフォームが壊れて送信される可能性がありますか?私は別のdicrepancyを見つけた :

は正確にindex.js

this.router.post('/login', ... 

EDITのようなルートを登録してください。 AuthenticateControllerでは、res.redirect("/content");はコールバック内で折り返されません。したがって、実行中はAuthenticateの実行が完了する前に実行されています。

index.js例では、パスポートは、ルートミドルウェアとして使用されている:

app.post("/login", 
    passport.authenticate("local-login", { failureRedirect: "/login"}), 
    function (req, res) { 
     res.redirect("/content"); 
    }); 

passport.jsにそれがコールバックの内側にあるが。ルートでそれを宣言する考えてみましょう:

registerRoutes() { 
    this.router.post('/login', this.passport.authenticate("local-login", { failureRedirect: "/login"}), this.login.bind(this)); 
    (...) 
} 

login(req, res) { 
    res.redirect("/content"); 
} 

O、いっそのこと、それはあなたがやっていることの全てであると思われるので、なぜ、passport's option to declare both success and failure redirectsを使用しない:

login(req, res) { 
    this.passport.authenticate("local-login", { successRedirect: "/content", failureRedirect: "/login" }); 
} 
+0

の下にあります。試してみましたが、役に立たないです。私はChrome Plugin ARCを使ってリクエストを送信しています。他のアイデア? –

+0

@elsololo私の編集を見てください。私はあなたを助けることができるいくつかの他の変更を提案しました – fmello

1

this.router.post('/login/:username/:password', this.login.bind(this));しかしlogin(req, res)へのミドルウェアは唯一あなたがユーザーとの何かをするコールバックを指定する必要があり、言ったようにそう/コンテンツへ

をリダイレクトres.redirect("/content");すなわちで要求に応答するようあなたはthis.login.bind(this)を渡していますパスポートミドルウェアの確認コールバックから返されます。あなたが明示的にセッション、エラーメッセージを設定し、要求をリダイレクトのコントロールを持っているしたい場合は

app.post("/login", 
    passport.authenticate("local-login", { failureRedirect: "/login"}), 
    function (req, res) { 
    console.log(req.user); // log user in console 
    res.json({user: req.user}); // send user as json response 
}); 

@divsingh言及カスタムコールバックがあります。他の情報はhttp://passportjs.org/docs

関連する問題