現在node.jsの学習でログイン機能の作成を行っています。
アカウント作成画面でユーザー名を入力した際にデータベースに問い合わせて入力されたユーザー名が既に登録されているか確認したいのですが
htmlのテキストボックスの入力イベント→node.jsでデータベースに問い合わせてユーザー名が既に登録されているか確認したいのですがnode.jsの場合はどのように処理すればよいのでしょうか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/12/24 04:48
2020/12/24 07:24
回答1件
0
ベストアンサー
まずはログイン認証周りに関して見ていきましょう
- ブラウザでWebサイトにアクセス
- フォームにログイン情報(IDやPASS等)を入力してサブミット
- サーバはログイン情報をデータベースに照合し、セッションIDを発行し、クッキーへの書き換え要求を出す
- ブラウザはクッキーで書き換え要求をだされたセッションIDを保管
ブラウザがWebサイトにアクセスする場合、
HTTPリクエストのヘッダー部分にクッキーをベタっと貼り付けて要求を行います。
サーバはこれを閲覧して、「君は既にログイン中なんだね」という事を見分けて2度目以降のアクセスがフリーパスとなります。
PHPは単独でWebサーバになる事はなく、
もっぱらApacheのオマケ(mod_phpモジュール)として動かす設計になっています。
裏でPHPのプロセスを4個程度同時並行で立ち上げておき、
index.php等が呼ばれたらそのプロセスを経由して動的なHTMLを払い出して
HTTPレスポンスとして返すような作りになっています。
しかし、1件1件のHTTPリクエストというのは完全に別プロセスとして閉じています。
Aユーザーがログイン認証を行っても、
別ページに行く時にはプロセスが別=変数が毎回リセットされてしまうので、
Aユーザーがログイン認証を行ったという結果もリセットされてしまうのです。
PHPではセッションという
HTTPアクセスを跨ぐ情報の保管庫みたいな機能を利用して解決しています。
この中にログイン認証が成功したユーザーの情報を保管する事で、
HTTPリクエストを跨いでそのユーザーが認証しているのかいないのかを見分ける事が多いです。
これはApache側に情報を持たせておいて、
どのPHPプロセスでもアクセス出来るという感じの仕組みになっています。
より大規模になって、複数マシンで並列で動作するようになると
セッション機能では対処出来ないので、
高速なキャッシングサーバ、Redis等を利用して、
その中にJSONみたいな文字列のデータを突っ込んでセッションの代替をさせる仕組みになるでしょう。
恐らくCakePHPやLaravel等のWebフレームワークを使ってきたと思いますので、
この辺の流れは何となく……な理解だったと思いますが、これをNode.jsでやることになります。
Node.jsは単独でWebサーバになります。
PHPのようにApacheにTCP80番ポートを専有させ、
index.phpを踏ませたらPHPプロセスを経由して……というやり方ではありません。
自分でApacheとPHPの部分を全部Node.jsで書けって話になります。
なんだそれは……実装が大変過ぎて死んでしまう……
なので、RubyでWebサーバを構築したければRuby on Railsを使うのが当然のように、
Node.jsでもWebフレームワークを利用するのが普通です。
Node.jsではExpressが人気で、
koaやfastifyといったクローンWebフレームワークが沢山作られています。
まずはExpress流儀のWebサイト構築に慣れ、
そこから他のWebフレームワークを試してみるのが良いでしょう。
公式サイトの上側に「解説」「ガイド」「APIリファレンス」という項目があり、
Webエンジニアとしての知識があればそこを読むだけでわりと何とかなる充実度の情報は得られます。
Node.js + Express流儀のチュートリアル
ざっと作ってみました。
bash
1# まず何かしらのディレクトリを作ってプロジェクトとする 2$ mkdir test-web 3 4$ cd test-web 5 6# プロジェクトルートにpackage.jsonファイルを作る事 7# Node.jsのプロジェクトという明示になる 8$ npm init --yes 9 10# node_modulesというフォルダを生成してexpressモジュールを突っ込む 11# package.jsonに導入したモジュールの情報が書き込まれるので…… 12$ npm install express 13 14# 2度目以降はこれでOK 15# 本番環境はモジュール名を記述せずにこれを入力すると導入出来る 16$ npm install 17 18$ touch index.js
.gitignoreでnode_modules
を除外しておく
node_modules/
js
1// require関数を実行することでnode_modulesに保存したモジュールを呼び出す事が可能 2const express = require("express"); 3 4const app = express(); 5const port = 3000; // まずは3000番等で様子見 6 7app.get('/', (req, res) => { 8 res.send('Hello World!') 9}); 10 11app.listen(port, () => { 12 console.log(`Example app listening at http://localhost:${port}`) 13});
実行する時はnode
コマンドを使って実行しましょう。
コードの修正があったらCtrl-cで終了して再度実行します。
bash
1$ node index.js
まずはこれを雛形に肉付けしていってみてください。
- セッションIDの実装→後述
- postの値の取得方法: [Node.js][Express]リクエストからパラメータを取得する・POSTされたデータを取得する
- HTMLテンプレート: 公式サイトのドキュメント
- データベースの読み書き: mysql2
- Cookieの読み書き: ExpressでCookieを利用する方法
セッションIDの実装に関して
Express流儀ではindex.js
ファイル内にapp
という変数を宣言しますので
同じスコープにオブジェクトの変数なんかを定義しておけばWebサーバを落とさない限り有効になります。
js
1const express = require("express"); 2 3const app = express(); 4const port = 3000; 5 6const session = {}; // 空の汎用オブジェクトを宣言 7 8// この辺は勉強する内に追加されていきます 9app.use(bodyParser.urlencoded({ extended: true })); 10app.use(cookieSession()); 11 12app.get('/', (req, res) => { 13 const sessionId = req.cookies.session; 14 console.log(session[sessionId]) 15 res.send('Hello World!'); 16}); 17 18app.post('/login', (req, res) => { 19 const sessionId = "1234abcd"; // 乱数作るのは課題 20 // データベースの認証が成功したらセッションに保存 21 session[sessionId] = { 22 id: 1, 23 name: "taro", 24 }; 25 // cookieにIDを保存 26 res.cookie('session', sessionId, { 27 maxAge: 60000, 28 httpOnly: false 29 }) 30 31 // 認証成功したらリダイレクト 32 res.redirect("/"); 33}); 34 35app.listen(port, () => { 36 console.log(`Example app listening at http://localhost:${port}`); 37});
こういう感じになっていくはずです。
htmlのテキストボックスのonchangeイベントをnode.jsで処理する方法はあるでしょうか?
ありません。
まぁ、言いたい内容はわかりますし実現は出来るんですが、
どのレイヤーかをちゃんと押さえておく必要があります。
JS上のonchangeイベントは
Webサーバとは何の関係もありません。
Webサーバの仕事はHTTPリクエストを待ち受け、適切なHTTPレスポンスを返すことだけが仕事です。
ブラウザがHTMLを受け取って画面を描画している時点でWebサーバの仕事は終わっています。
JavaScript(以下JS)とNode.jsこれは全く違うものです。
ブラウザがHTMLを受取り、DOMツリー構築を行い画面レンダリングを行った後に、
DOMツリーを後から書き換えて画面の更新をするものがJSです。
JSにはブラウザ上でDOMを書き換える機能しかありません。
Node.jsはJSをRubyやPythonのような汎用スクリプト言語として使いたい人が居まして、
変数や配列等のメモリ確保等の機能はGoogle社が開発しているV8エンジンを借りてきて
C++で作ったOSの機能を使うモジュール、ファイルの読み書き、外部ライブラリ読み込み、自由なネットワーク通信などなど……の機能を継ぎ足して完成した魔改造JSがNode.jsです。
Node.jsというJSファイルが動作する汎用スクリプト言語は人気が出ましたが、
JSそのものはブラウザ上でDOMツリーを書き換える言語でしかありません。
それが質問に対する回答「ありません」になります。
じゃあそれをどうやって実現させるか?
基本的にはAjaxを実装する方針が無難です。
JSではブラウザの力を借りてHTTPリクエストを飛ばす事が出来ます。
ブラウザに渡すHTMLをこんなふうに作っておきます。
すると、div
要素をクリックすると、
Fetch APIの機能を使ってWebサーバの/api/data
にデータを取りに行きます。
html
1<script> 2const getData = () => { 3 // JSONを期待して変換するロジックを組んでみた 4 fetch("/api/data") 5 .then(res => res.json()) 6 .then(data => { 7 console.log(data); 8 }); 9} 10</script> 11<div onclick="getData()"> 12 aaa 13</div>
Node.jsのWebサーバも準備しましょう。
上記では/api/data
に向かってHTTPリクエストを出しているはずなので、
/api/data
のパスにHTTPリクエストが飛んできたら受け取れるようにしておきます。
js
1const express = require("express"); 2 3const app = express(); 4const port = 3000; // まずは3000番等で様子見 5 6app.get('/', (req, res) => { 7 res.send('Hello World!') 8}); 9 10app.get('/api/data', (req, res) => { 11 // こんな風にJSONを返す 12 res.json({ 13 id: 1, 14 name: "taro" 15 }); 16}) 17 18app.listen(port, () => { 19 console.log(`Example app listening at http://localhost:${port}`) 20});
このような流れを設計・作成し、
二人三脚で作っていく形になります。
投稿2020/12/24 09:13
編集2020/12/24 12:08総合スコア21203
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/12/24 11:40
2020/12/24 11:45
2020/12/24 12:06
2020/12/24 14:31
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。