1

バックエンド: Sails.js

REST API 用の JSON Web Token を既に実装しています。フロントエンドからさまざまなコントローラーのアクションへのすべての AJAX 要求は、res.json(data);Authorization ヘッダーを介して正しい JWT を受信した場合にのみデータを返します。期待どおりに動作します。

今、私は EJS を使用してビューを作成しました<%= name =>。コントローラーには詳細がres.view('/home', {name: "Bill"} );あり、それぞれのコントローラーを指すようにルートも構成されています。

属性を持つサーバー側ビューから既に発行された JWT (localStorage に格納されている) で認証することにより、コントローラーから「名前」を取得するにはどうすればよいですか?<%= name =>

ありがとう。

コード:

ビュー/index.ejs

<%= name =>

API/コントローラー/UsersController.js

info: function(req, res) {

var userId = req.token;

Users.findOne(userId).exec(function(err, profile) {
    if(err) {
    res.json(err);
    } else {
       res.view('index',{
        name: profile.name,
    });
    }
});        
},

API/ポリシー/tokenAuth.js

module.exports = function(req, res, next) {
  var token;

  if (req.headers && req.headers.authorization) {
    var parts = req.headers.authorization.split(' ');
    if (parts.length == 2) {
      var scheme = parts[0],
        credentials = parts[1];

      if (/^Bearer$/i.test(scheme)) {
        token = credentials;
      }
    } else {
      return res.json(401, {err: 'Format is Authorization: Bearer [token]'});
    }
  } else if (req.param('token')) {
    token = req.param('token');
    delete req.query.token;
  } else {
    return res.json(401, {err: 'No Authorization header was found'});
  }

  sailsTokenAuth.verifyToken(token, function(err, token) {
    if (err) return res.json(401, {err: 'Please Logout and Login again!'});

    req.token = token;

    next();
  });
};

API/サービス/sailsTokenAuth.js

var jwt = require('jsonwebtoken');

module.exports.issueToken = function(payload) {
  var token = jwt.sign(payload, process.env.TOKEN_SECRET || "xxxxxxx");
  return token;
};

module.exports.verifyToken = function(token, verified) {
  return jwt.verify(token, process.env.TOKEN_SECRET || "xxxxxxx", {}, verified);
};

config/routes.js

module.exports.routes = {
    '/': {
        controller: 'UsersController',
        action: 'info'
      },
};

解決:

JWT をクライアント ブラウザからサーバーへの認証要素として使用するには、localStorage またはセッション Cookie を使用できます。サーバーでの実装が簡単になったため、最終的にCookieの使用に絞り込みました。

ユーザーを認証した後、JWT をクライアントのブラウザーに保存します。

res.cookie('jwttoken', sailsTokenAuth.issueToken(profile.name));

次に、サービス (jwt.verify) を使用して取得および検証し、またはreq.cookies.jwttoken経由で要求された情報にアクセスできます。res.jsonres.view

4

1 に答える 1

6

提供されていないため、コードを表示できませんが、カスタム ポリシーapi/policies/jwt.jsなどを設定し、そこでリクエストごとに JWTToken を確認するとします。次のようなものです(簡単にするためにエラー処理は無視します):

module.exports = function (req, res, next) {

    var token = req.headers.authorization.split(' ')[1];
    var payload = jwt.decode(token, config.TOKEN_SECRET);
    req.userId = payload.sub;
    next();
};

reqオブジェクト ( req.userId = payload.sub; )に userId を追加したことに注意してください。つまり、controllerでは、着信reqオブジェクトから簡単に参照できるため、userId (または、あなたの場合は、ログインしているユーザーを識別するために使用している ID など) にアクセスできます。

明らかに、JWT ポリシーの実装は異なる場合がありますが、上記のようにカスタマイズしてください。実際にjwt トークン自体に名前を保持している場合(実装が表示されない場合)、これを req オブジェクトに追加するだけです (モデルのルックアップは必要ありません)。

必要なnameを取得したら、それをビューに渡します (現在、上記のハードコードされた値Bill .

更新された質問に基づいて更新

コメントと更新された質問に基づいて、JWT トークンからプロファイル情報を抽出し、モデル ルックアップから必要なプロファイル情報を取得することができました。その名前を EJS ビューに表示できなくなりました。

したがって、次のようにこれを達成できます。

コントローラ:

res.view('index', {
        name: profile.name
    }

profile.name の後のコンマを削除したことに注意してください ;)

config/views.jsを使用しているテンプレート エンジンの場合は、「ejs」に設定する必要があります。

残りは良さそうです。少なくとも、私が期待していたものと一致しています。

あなたの最善の策は、デバッガーを明示的に使用するか、少なくとも console.log ステートメントを controller.info メソッドが戻る直前まで使用し、 profile.name が期待どおりに設定されていることを確認することです。そこまで行くと、どうにか表示するためのルーティングに問題があることがわかります。

ビューの下にサブフォルダーを作成し、ビュー ファイルの名前を変更することもできます (インデックスは少し特殊です..)。views/xxx/yyy.ejsのようなことを行います

また、controller.info メソッドを一時的にコメントアウトし、次のような非常に単純なものに置き換えます。

res.view('xxx/yyy', {
            name: 'bob'
        });

ユーザーからのさらなるフィードバックに基づくさらなる更新

あなたの最後のコメントから、あなたの質問は徐々に進化しています...

あなたが今言っていると思うのは、Sails コードはすべて機能しており、Postman を使用して機能することが証明されているということです。ただし、クライアント コードが http ヘッダーで正しいトークン情報を渡していないため、Web ブラウザー クライアントを使用すると失敗します。

その場合は、ヘッダー情報をプログラムで適用するインターセプターをクライアントに作成する必要があります。

例えば。(Angular ファクトリ authInterceptor から取得したスニペットにすぎませんが、角度固有のものはここに示されていません):

 request: function (config) {
      var token = authToken.getToken();

      if (token) {
        config.headers.Authorization = 'Bearer ' + token;
      }

      return config;
    },

上記では、要求に応じて、JWT がローカル ストレージから取得され (作業していると言います)、トークンが存在する場合は、http ヘッダー情報が「Bearer token」形式の認証ヘッダーで更新されます。

私はあなたのレポを見ていませんが、正直なところ、すでにたくさんの情報を提供したと感じています。私が提供したものに基づいて、おそらくもう少しグーグル/テストを行うことで、実用的なソリューションを得ることができるはずです.

于 2016-01-16T10:14:21.380 に答える