2017-05-15 21 views
-1

これは少し新しくなっています。 Node.jsとExpress.jsでREST APIを作成しました。一部のルートには認証ミドルウェアがあります。これらのルートを使用するには、検証されるユーザーの認証トークンを使用してヘッダーを設定する必要があります。私は、ローカルストレージを使用している静的サイトでこれを問題なく実行してきました。私は最初の動的サイトを(エクスプレスを使用して)作成しています。特定のルートでは、ページを表示するために必要なすべてのデータをロードするミドルウェアがあります。ローカルストレージのヘルプがないので、認証トークンにアクセスして使用するにはどうすればよいですか?Expressミドルウェアでの認証

EDIT(説明のため): これは、データベース(mongoDB)からすべてのトランザクションをフェッチするAPIルートの1つです。

app.get('/transactions', authenticate, (req, res) => { 
    Transaction.find().then((transaction) => { 
    res.send({transaction}); 
    }, (e) => { 
    res.status(400).send(); 
    }); 
}); 

これは実行される認証ミドルウェアです。

var authenticate = (req, res, next) => { 
    var token = req.header('x-auth'); 

    User.findByToken(token).then((user) => { 
     if (!user) { 
      return Promise.reject(); 
     } 
     req.user = user; 
     req.token = token; 
     next(); 
    }).catch((e) => { 
     res.status(401).send(); 
    }); 
}; 

ここで私の高速ウェブサーバー上で、私はすべてのデータを取得するためにgetTransactionsを使用する次のルートを持っています。 (これは私がハンドルバーに表示)

router.get('/orders', getTransactions, (req, res) => { 
    res.render('orders.hbs', { 
    transaction: req.transactions.data.transaction 
    }); 
}); 

、これは私がちょうどウェブサーバとして明示使用せずに静的なサイトを作っていたときに、私はちょうどにユーザーのサインを持っているでしょうミドルウェア

var getTransactions = (req, res, next) => { 
    axios.get('https://serene-wave-28270.herokuapp.com/transactions') 
    .then((response) => { 
     req.transactions = response; 
     console.log(req.transactions.data.transaction); 
     next(); 
    }).catch((e) => { 
     console.log(e); 
    }) 
} 

ですauthトークンをローカルストレージに保存します。また、最初の2つのブロックは私のapiから、下の2つはウェブサーバーから、それぞれHeroku上で別々にホストされていることに注意してください。私はそれが標準的な設計かどうか分からないので、私はそれを言及すべきだと思った。

答えて

0

あり、詳細の全体の多くは、あなたがやろうとしている正確に何のためにあなたの質問にはいないのですが、私はExpressで使用可能な一般的な概念を説明することができます:

Expressの通常のスキームが認証することですユーザが認証されたことを示すセッションCookieを設定します。クッキーは自動的にブラウザによって保存され、その後、リクエストごとに自動的にブラウザからサーバーに送信されるので、サーバーがサーバー側のセッションを識別するために使用できるクッキーを取得し、必要な情報を使用することができますページを作成したり、そのユーザーのAPI要求に応答したりするときに、セッション(ユーザー識別情報またはセッションオブジェクトに格納されている他の状態)から取得します。

NPMモジュールexpress-sessionは、セッションオブジェクト、セッションクッキーを自動的に作成し、要求ごとに2つを一緒にフックするため、この作業の多くを処理します。一方で、あなたはすでにクライアントで認証トークンを持っていて、ちょうどそれが自動的にすべてのリクエストでサーバに通信したい、場合


、その後、あなただけのクッキーにその認証トークンを置くことができますサーバーが各要求時にクッキー内でそれを探すようにします。クッキーをHttpOnlyに設定することで、クライアント側のJavascriptから認証トークンにアクセスできないようにする(これはサーバーのアクセス能力には影響しません)。

+0

おかげで、私は特急セッションは私が必要なものかもしれないと思います。あまりにも漠然として申し訳ありませんが、あなたの答えが変わったら、いくつかのコードを追加しました! –

+0

@S_Farsai - 新しいコードショーのように認証トークンを使い続ける場合は、ヘッダーからクッキーに移動するだけで、そのクライアントからのすべてのリクエストに自動的に含まれます。これにより、ローカルストレージを使用する必要がなくなり、すべての要求にトークンが自動的に含まれます。 – jfriend00

+0

素晴らしいですよ!私は緑色のチェックを与えた –

0

あなたの質問には詳細はほとんどありませんが、ここにいくつかの考えがあります。

あなたはとてもreq.headersてヘッダにアクセスすることができます(@ jfriend00以下で詳述)クッキーを使用するか(私は以下の記述がある)有効な認証トークンをチェックするためにエクスプレスで

を要求ヘッダーを使用しますか、 の前にのミドルウェアを書き込んで、現在のミドルウェアがすべてのデータをロードして、ユーザーが次のミドルウェアを呼び出すためにnext()を呼び出すことを許可されていることを確認するか、またはカスタムエラータイプを使用して、彼は(next(err)他のすべてのミドルウェアをスキップし、エラーミドルウェアにジャンプする)

例えば

(あなたはどこかに定義されたAuthorizationErrorという名前のエラーのサブクラスを持っていると仮定):あなたの応答のための

const express = require('express'); 
const AuthorizaztionError = require('<some path>'); 
const app = express(); 

function checkAuthTokenMiddleware(req, res, next) { 
    if (req.headers && req.headers.authorization) { 
     let token; 
     const parts = req.headers.authorization.split(' '); 
     if (parts.length == 2) { 
      const [scheme, credentials] = parts; 

      if (/^Bearer$/i.test(scheme)) { // or any other scheme you are using 
       token = credentials; 
      } 

      if (token === undefined) { 
       // access token - missing 
       return next(new AuthorizationError(
        "Invalid access token.", // error_description 
        "invalid_token" // error 
       )); 
      } 
      // add something here to ensure the token is valid 
      return next(); 
     } 
    } else { 
     // No authorization header => invalid credentials 
     return next(new AuthorizationError(
      "Authorization header required.", // error_description 
      "invalid_request" // error 
     )); 
    } 

} 

// Add this in your route declaration 
app.use(
    "/auth/test", 
    checkAuthTokenMiddleware, 
    function(req, res, next) { 
     // do something 
    } 
); 

// this must come last 
app.use(function errorMiddleware(err, req, res, next) { 
    // return something 
    if (err instanceof AuthenticationError) { 
     // do something for example 
     res.status(401).send(err.error_description); 
    } else { 
     // generic error handling, for example 
     res.status(500).send("Error "+err); 
    } 
}) 

// ... 
+0

ちょっとボリス、答えに感謝します。あまりにも漠然として申し訳ありません。私が助けになる場合の明確化のためのコードをいくつか追加しました –

関連する問題