node.jsとは何か、そしてそれをどのように使用するかを既に知っているとしましょう。 また、メインページといくつかの追加のページを備えたシンプルなサイトを既に持っていると仮定しましょう。 このようなサイトのソースは、この記事の例です。
理論
セッションのようなものがあります-ユーザーがサイトにいる間の時間です。 セッションは、ユーザーがブラウザーで最初にサイトを開いたときに始まり、有効期限が切れたときに(またはサイトが中断したいときに)終了します。 各セッションは、特定のデータセットに関連付けられています。
- 一意のセッション識別子
- 有効期間
- ユーザー名(入力した場合)
- 識別に必要なその他のサービス情報:IPアドレス、ユーザーエージェント
- サイトが現在のユーザーに関連付けるその他の情報。 たとえば、電子ストアは、セッションにバスケットに追加された製品のリストを保存できます。
この問題を解決するには、データベースに2つのテーブルが必要です。1つはセッションデータを保存し、もう1つはユーザーに関する情報を保存します。 実際、この場合、「DBテーブル」と言うのは完全に正しいわけではなく、情報は異なる場所にある可能性があります。 たとえば、すべてのセッションパラメータはCookie (またはアプリケーションのメモリ、これは良くありませんが)に保存できます。 OpenID / OAuthを使用してログインする場合、ユーザーデータは外部から取得できます。
つなぐ
connect
は、セッションを作成するすべての作業を処理します。 これを行うには、2つのルールを追加します。
app.use(connect.cookieParser()); app.use(connect.session({ secret: 'your secret here'} ));
順序は重要です。ルートを定義する前に、ルール自体を定義する必要があります。 最初のルールは、一般的なクッキーの使用を規定しています。 2番目は、
session
データを利用できる通常の
request
session
フィールドを追加します(例でより明確になります)。
connect.session
は、次のパラメーターを受け取ります。
-
secret
-Cookie内の情報を暗号化するために使用されるフレーズ。 -
store
セッションデータを保存するために使用されるオブジェクト。 デフォルトでは、connectはすべてのデータをメモリに保存しますが、実際のアプリケーションではこれを実行できません。 mongodb 、 redis 、 MySQLなどの既製のソリューションがあります 。 -
cookie
はcookieパラメーターのセットです。 最も重要なのはmaxAge
、ミリ秒単位のライフタイム(またはnull)です
ログイン
既に述べたように、
connect
は各リクエストに
session
フィールドを追加しますが、デフォルトではそこに興味深いものはありません。 ユーザーを何らかの方法で「認識」する場合(実際、ユーザーが正しいパスワードを入力した場合)、ユーザーに関する情報をセッションに追加する必要があります。 このようなもの:
if ((request.body.login==='Thor')&&(request.body.password==='111')) { request.session.authorized = true; request.session.username = request.body.login; console.log('Thor is here!'); }
原則として、1つの
username
変数で十分です( この記事の著者が行うように)。 ただし、ユーザーが承認されているかどうかを確認すると、見苦しくなります。
if (typeof req.session.username == 'undefined') { // , }
ユーザーがログアウトする場合、追加されたフィールドを削除するだけで十分です。
delete req.session.authorized; delete req.session.username ;
完全なクリーニングのために、 session.destroy()メソッドがあります。 現在のリクエストから
session
を削除し、次回このフィールドが再生成されます。
アクセス制御
最も明らかな解決策は、安全なページを生成する必要があるときはいつでもrequest.session.authorizedをチェックすることです。 実際、これはすでに言及した記事で行われています。 問題は、これが「階層化」
connect
イデオロギーと矛盾
connect
ことです。 ユーザーの権限を確認し、何か問題が発生した場合はエラーページにリダイレクトする特別なルールを設定することをお勧めします。 アイデアはここで説明されていますが、私たちの場合は
// , ; var siteUrls = [ {pattern:'^/login/?$', restricted: false} , {pattern:'^/logout/?$', restricted: true} , {pattern:'^/$', restricted: false} , {pattern:'^/single/\\w+/?$', restricted: true} ]; function authorizeUrls(urls) { function authorize(req, res, next) { var requestedUrl = url.parse(req.url).pathname; for (var ui in urls) { var pattern = urls[ui].pattern; var restricted = urls[ui].restricted; if (requestedUrl.match(pattern)) { if (restricted) { if (req.session.authorized) { // , next(); return; } else{ // , res.writeHead(303, {'Location': '/login'}); res.end(); return; } } else { next(); return; } } } // , console.log('common 404 for ', req.url); res.end('404: there is no ' + req.url + ' here'); } return authorize ; } app.use('/', authorizeUrls(siteUrls));
それだけです これが誰かを助けることを願っています。