2017-10-31 16 views
1

私はパスポートライブラリを使ってapiの要求を認証しようとしています。まず、ExpressフレームワークでNodeJSアプリケーションを作成しました。プロジェクトには、いくつかのデータを提供するapiが含まれています。パブリックフォルダには、ユーザー名とパスワードフィールドを持つindex.htmlページが含まれています。正しい方法でpassport.jsを使用する方法

Index.htmlと

<form action="/login" method="post"> 
    <div> 
     <label>Username:</label> 
     <input type="text" name="name"/> 
    </div> 
    <div> 
     <label>Password:</label> 
     <input type="password" name="password"/> 
    </div> 
    <div> 
     <input type="submit" value="Log In"/> 
    </div> 
</form> 

は、httpサーバを作成server.tsを作成し、いくつかのポートでリッスンし、特急のフレームワークを使用してAPIを作成しました。

Server.ts

let userList: User[] = [new User(1, "Sunil"), new User(2, "Sukhi")]; 

let app = express(); 

// passport library 
let passport = require('passport'); 
let LocalStrategy = require('passport-local').Strategy; 

// middlewares 
app.use(express.static("public")); 
app.use(bodyParser.json()); 
app.use(bodyParser.urlencoded({ extended: false })); 
app.use(session({ resave: false, saveUninitialized: true, secret: "secretKey123!!" })); 

// passport middleware invoked on every request to ensure session contains passport.user object 
app.use(passport.initialize()); 
// load seriliazed session user object to req.user 
app.use(passport.session()); 

// Only during the authentication to specify what user information should be stored in the session. 
passport.serializeUser(function (user, done) { 
    console.log("Serializer : ", user) 
    done(null, user.userId); 
}); 

// Invoked on every request by passport.session 
passport.deserializeUser(function (userId, done) { 
     let user = userList.filter(user => userId === user.userId); 
     console.log("D-serializer : ", user); 
     // only pass if user exist in the session 
     if (user.length) { 
      done(null, user[0]); 
     } 
}); 
// passport strategy : Only invoked on the route which uses the passport.authenticate middleware. 
passport.use(new LocalStrategy({ 
    usernameField: 'name', 
    passwordField: 'password' 
}, 
    function (username, password, done) { 
     console.log("Strategy : Authenticating if user is valid :", username) 
     let user = userList.filter(user => username === user.userName) 
     if (!user) { 
      return done(null, false, { message: 'Incorrect username.' }); 
     } 
     return done(null, user); 
    } 
)); 

app.post('/login', passport.authenticate('local', { 
    successRedirect: '/done', 
    failureRedirect: '/login' 
})); 

app.get('/done', function (req, res) { 
    console.log("Done") 
    res.send("done") 
}) 

app.get('/login', function (req, res) { 
    console.log("login") 
    res.send("login") 
}) 

// http server creation 
let server = http.createServer(app); 

server.listen(7000,() => { 
    console.log('Up and running on port 7000'); 
}); 

私はlocalhostを打ったとき今:7000を、私はそれがそうでなければ、ログイン行わ返しuserListからのユーザー名で提出クリックしたときには、ログインページが開きます。これは問題ありません。

すべてのコールは、deserializeUserメソッドを経由します。

問題は、他のURLを直接呼び出すときに(ユーザーを認証する)、正常に動作してデータを返すということです。

要求が認証されない場合、deserializeUserがすべての要求を傍受しているため、他のすべての呼び出しが失敗することが予想されましたが、この場合はパスポート方式は呼び出されません。

これはどのように動作するのですか?または私は何かを欠いている?

答えて

0

私はすべての認証にミドルウェアがありませんでしたその後の要求だからisAuthenticatedメソッド(thanks @Sombrero)を作成しました。

すべての要求

app.get('/done', isAuthenticated, (req, res) => { 
    res.send("done") 
}); 

// request interceptor that will check user authentication 
private static isAuthenticated = (req, res, next) => { 
    console.log("Authenticating :", req.originalUrl) 
    if (req.isAuthenticated()) { 
     return next(); 
    } 
    res.redirect('/login'); 
}; 

、その後、これはすべてのリクエストでisAuthenticatedメソッドを使用して大変でした。だから私は、公開されたAPIリストの配列を作成し、すべての要求を傍受するためのミドルウェアを追加し、公開API

​​3210

を無視するisAuthenticated方法を更新してから

app.use(Server.isAuthenticated) 
2

あなたはあなたのユーザーが認証されている場合は、チェックのために、ミドルウェアを追加する必要があります。

isAuthenticated = (req, res, next) => { 
    if (req.isAuthenticated()) { 
     //if user is logged in, req.isAuthenticated() will return true 
     return next(); 
    } 
    res.redirect('/login'); 
}; 

そして、あなたがそのようにそのミドルウェアを使用する必要があります。

//if user not authenticated, he will be redirect on /login 
app.get('/done', isAuthenticated, (req, res) => { 
    res.send("done") 
}); 
+0

は、あなたがこれを思ういけないのミドルウェアとして、この方法を使用しました自動でなければなりません。すべてのリクエストに対してミドルウェアを置くべきではないことを意味します。 –

+0

いいえ、自動ではないので、アクセスするためにログインする必要のあるパブリックとルートを選択できます – Sombrero

関連する問題