ホームページ  >  記事  >  ウェブフロントエンド  >  ノードを使用してトークンベースの認証を実装する方法

ノードを使用してトークンベースの認証を実装する方法

php中世界最好的语言
php中世界最好的语言オリジナル
2018-05-25 14:50:081253ブラウズ

今回は、node を使用してトークンベースの認証を実装する方法と、node を使用してトークンベースの認証を実装する際の注意事項について説明します。実際のケースを見てみましょう。

最近、トークンベースの認証を研究し、このメカニズムを個人プロジェクトに統合しました。現在、多くの Web サイトの認証方法は、従来のセッション + Cookie からトークン検証に移行しています。従来の検証方法と比較して、トークンは優れたスケーラビリティとセキュリティを備えています。

従来のセッション+Cookie認証

HTTPはステートレスであるため、ユーザーのIDは記録されません。ユーザーがアカウントとパスワードをサーバーに送信した後、バックグラウンドで検証は通過しますが、ステータスは記録されないため、次のユーザーのリクエストでは引き続き ID を検証する必要があります。この問題を解決するには、サーバー側でユーザーの ID を含むレコード (セッション) を生成し、このレコードをユーザーに送信して、ユーザーのローカル領域 (つまり Cookie) に保存する必要があります。 。次に、ユーザーのリクエストによってこの Cookie が送信され、クライアントの Cookie とサーバーのセッションが一致する場合、ユーザーの ID 認証が成功したことになります。

トークンの本人確認

プロセスは大まかに次のとおりです:

  1. 最初のリクエストを行うとき、ユーザーはアカウントとパスワードを送信します

  2. バックグラウンド検証に合格すると、時間効率の良いトークンが発行されます。生成され、このトークンがユーザーに送信されます

  3. ユーザーがトークンを取得した後、トークンはローカルに (通常は localstorage または cookie に) 保存されます

  4. 後続の各リクエストでは、このトークンがリクエスト ヘッダーに追加されますすべてを検証する必要がある すべての ID インターフェイスはトークンを使用して検証されます。トークンによって解析されたデータにユーザー ID 情報が含まれている場合、ID 検証は合格します。

従来の検証方法と比較して、トークン検証には次の利点があります:

  1. トークンベースの認証では、トークンは認証情報をセッションや Cookie に保存するのではなく、リクエスト ヘッダーを通じて送信されます。これは無国籍を意味します。 HTTP リクエストを送信できる任意の端末からサーバーにリクエストを送信できます。

  2. CSRF攻撃を回避できる

  3. アプリケーションでセッションが読み取り、書き込み、または削除されるとき、少なくとも初回は、オペレーティング システムの一時フォルダーでファイル操作が発生します。複数のサーバーがあり、最初のサービスでセッションが作成されると想定します。リクエストを再度送信し、そのリクエストが別のサーバーに到達すると、セッション情報が存在せず、「認証されていない」応答が返されます。この問題はスティッキー セッションで解決できます。しかし、トークンベースの認証では、この問題は自然に解決されます。サーバーに送信されるすべてのリクエストでリクエスト トークンがインターセプトされるため、スティッキー セッションの問題は発生しません。

以下は、node+jwt (jwtチュートリアル)を使用して簡単なトークンID検証を構築する方法の紹介です

ユーザーが初めてログインするときに、アカウントとパスワードをサーバーに送信します、サーバー検証に合格し、対応するトークンを生成します。コードは次のとおりです:

const fs = require('fs');
const path = require('path');
const jwt = require('jsonwebtoken');
//生成token的方法
function generateToken(data){
  let created = Math.floor(Date.now() / 1000);
  let cert = fs.readFileSync(path.join(dirname, '../config/pri.pem'));//私钥
  let token = jwt.sign({
    data,
    exp: created + 3600 * 24
  }, cert, {algorithm: 'RS256'});
  return token;
}
//登录接口
router.post('/oa/login', async (ctx, next) => {
  let data = ctx.request.body;
  let {name, password} = data;
  let sql = 'SELECT uid FROM t_user WHERE name=? and password=? and is_delete=0', value = [name, md5(password)];
  await db.query(sql, value).then(res => {
    if (res && res.length > 0) {
      let val = res[0];
      let uid = val['uid'];
      let token = generateToken({uid});
      ctx.body = {
        ...Tips[0], data: {token}
      }
    } else {
      ctx.body = Tips[1006];
    }
  }).catch(e => {
    ctx.body = Tips[1002];
  });
});
ユーザーは、検証を通じて取得したトークンをローカルに保存します:

store.set('loginedtoken',token);//store为插件
クライアントが身元検証を必要とするインターフェイスを要求した後、トークンは次のようになります。リクエストヘッダーに配置され、サーバーに渡されます:

service.interceptors.request.use(config => {
  let params = config.params || {};
  let loginedtoken = store.get('loginedtoken');
  let time = Date.now();
  let {headers} = config;
  headers = {...headers,loginedtoken};
  params = {...params,_:time};
  config = {...config,params,headers};
  return config;
}, error => {
  Promise.reject(error);
})
サーバーはトークンをインターセプトし、ログインを必要とするすべてのインターフェイスの正当性を検証します。

function verifyToken(token){
  let cert = fs.readFileSync(path.join(dirname, '../config/pub.pem'));//公钥
  try{
    let result = jwt.verify(token, cert, {algorithms: ['RS256']}) || {};
    let {exp = 0} = result,current = Math.floor(Date.now()/1000);
    if(current <= exp){
      res = result.data || {};
    }
  }catch(e){
  }
  return res;
}
app.use(async(ctx, next) => {
  let {url = ''} = ctx;
  if(url.indexOf('/user/') > -1){//需要校验登录态
    let header = ctx.request.header;
    let {loginedtoken} = header;
    if (loginedtoken) {
      let result = verifyToken(loginedtoken);
      let {uid} = result;
      if(uid){
        ctx.state = {uid};
        await next();
      }else{
        return ctx.body = Tips[1005];
      }
    } else {
      return ctx.body = Tips[1005];
    }
  }else{
    await next();
  }
});
この例で使用される公開キーと秘密キーは自分で生成できます。操作は次のとおりです:

  1. コマンド ライン ツールを開き、openssl を入力して開きます

  2. 秘密キーを生成します: genrsa -out rsa_private_key.pem 2048

  3. 公開キーを生成します: rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

この記事の事例を読んだ後は、この方法を習得したと思います。 、PHP 中国語 Web サイトの他の関連記事にも注目してください。

推奨書籍:

Angular プロジェクトで scss を使用する手順の詳細な説明

vue2.0+koa2+mongodb を使用して登録とログインを実現する方法

以上がノードを使用してトークンベースの認証を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。