CORSエラーの回避方法【Node.js】

■はじめに

CORSとは、「Cross Origin Resource Sharing」の略です。

このエラーは、異なるドメインからアクセスされた際に発生します。

つまり、localhostで実行しているWEBアプリから、サーバーにデプロイされているRestAPIを実行する時などで発生します。

例)「http://aaa.com/」のWebから「http://bbb.com/」のNode.jsを実行する。

ここでは、CORSエラーが発生しないようにする手順を記載します。(ライブラリは使用しません。)

■手順

express-generatorでプロジェクトが作成されている前提で記載します。

「app.js」の「app.use」が並んでいるところに、以下を追加します。

app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, DELETE");
next();
});

たったこれだけです。

あとは、サーバーを再起動して確認してください。

一応、以下に「app.js」の全量を載せておきます。(ほぼ自動生成ですが。)

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, DELETE");
next();
});
app.use('/', indexRouter);
app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;

Node.js Expressのexpress-generatorで作成したプロジェクトをHTTPS起動する方法【Node.js】

■はじめに

以下のリンク先のサイトで、express-generatorを使用してプロジェクトを作成しておいてください。

www.reigle.info

■手順

express-generatorで生成されたプロジェクトの「bin」配下の「www」を以下に書き換えます。

#!/usr/bin/env node
serverStart();
sslServerStart();
/**
* 通常(HTTP)のサーバー起動
*/
function serverStart() {
var app = require('../app');
var http = require('http');
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
var server = http.createServer(app);
server.listen(port);
server.on('error', onError);
console.log("ポート「" + port + "」でHTTPサーバーを起動しました");
}
/**
* SSL(HTTPS)のサーバー起動
*/
function sslServerStart() {
var app = require('../app');
var https = require('https');
var fs = require('fs');
var options = {
key: fs.readFileSync("[秘密鍵]"),
cert: fs.readFileSync("[証明書]")
};
var port = normalizePort(process.env.SSL_PORT || '4000');
app.set('port', port);
var serverS = https.createServer(options, app);
serverS.listen(port);
serverS.on('error', onError);
console.log("ポート「" + port + "」でHTTPSサーバーを起動しました");
}
/**
* ポートのバリデーションチェックして正しいポートを設定する
* @param val
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
return val;
}
if (port >= 0) {
return port;
}
return false;
}
/**
* エラー発生時のハンドリング
* @param error
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}

「[秘密鍵]」と「[証明書]」の部分は各環境に書き換えてください。

ちなみに、以下で取得した証明書の場合は以下のように記載できます。

www.reigle.info

var options = {
key: fs.readFileSync("/etc/letsencrypt/live/hogehoge.com/privkey.pem"),
cert: fs.readFileSync("/etc/letsencrypt/live/hogehoge.com/cert.pem")
};

「hogehoge.com」の部分は自分のドメインに書き換えてください。

HTTPSのポートを指定する方法

package.jsonの「scripts」を以下のように記載することで、HTTPとHTTPSのそれぞれのポートを指定できます。

"scripts": {
"start": "PORT=1234 SSL_PORT=5678 node ./bin/www"
},

「PORT」がHTTPのポートで「SSL_PORT」がHTTPSのポートです。

BitbucketにPushされた時に自動でサーバーにデプロイする方法【Node.js】

■はじめに

ここでは、BitbucketにPushされたことをトリガーにして、サーバーにソースコードをデプロイする方法を記載します。
Node.jsの環境やBitbucketに関しては、ある程度理解している前提で記載しますので、わからない部分は都度調べてください。

■手順

まずは、ソースコードの全量は以下です。

var exec = require('child_process').exec
var http = require('http');
var cmd = 'cd /var/www/html/ && git pull origin master';
/*コマンド実行関数*/
function update() {
return exec(cmd, {timeout: 90000},
function(error, stdout, stderr) {
if(error !== null) {
console.log(error);
}
}
)
};
http.createServer(function (req, res) {
if(req.method == 'POST'){
console.log("===deploy===");
update();
}
}).listen(3456);

基本的には、コピペでいいですが、以下だけ修正しないといけません。

以下は、実行するコマンドです。
cdコマンドのディレクトリを「.git」が格納されているディレクトリに指定してください。
また、pullした後に何かコマンドを実行したければ「&&」でつなげて記載してください。

var cmd = 'cd /var/www/html/ && git pull origin master';

以下は、利用するポート番号を指定しています。
このポート番号は、ファイアーウォールに穴あけをしておいてください。

}).listen(3456);

最後に、Bitbucketの「リポジトリ -> 設定 -> Webhooks」に上記のNodeの実行URLを記載しておいてください。
例)http://hogehoge.con:3456/

Node.jsでJWT(JSON Web Token)を生成/デコードする方法【Node.js】

■はじめに

RestAPIなどJWTを生成したい場面がちょくちょくあります。

ここでは、Node.jsでJWTを生成する方法と、生成したJWTをデコードして中身を見る方法を記載します。

※基本的なNode.jsの使い方などは割愛していますので、ご了承ください。

秘密鍵に関しては生成している前提で進めています。

■手順

以下のnpmコマンドでライブラリをインストールする。

npm i jsonwebtoken

以下をコピペして実行してみてください。(早速完成系ですw)

var jwt = require('jsonwebtoken');
// 本来なら直書きでは無く、「readFileSync」などで読み込んだ方が良さげだが、ここではローカル実行するために直書きしてます。
const PEM = `[秘密鍵の中の値]`
// var fs = require('fs');
// const PEM = fs.readFileSync('auth.pem')
// JWT生成関数
function issueToken() {
// headerの設定
const opts = jwt.SignOptions = {
algorithm: 'RS256',
issuer: 'https://issuer.example.com',
expiresIn: '1d'
}
// payloadの設定
const payload = {
sub: "TEST",
}
// headerとpayloadを元に秘密鍵でJWT化
return jwt.sign(payload, PEM, opts)
}
// JWTのデコード(引数にJWT)
function verifyToken(idToken) {
// headerの設定
const opts = jwt.VerifyOptions = {
algorithms: ['RS256'],
issuer: 'https://issuer.example.com',
maxAge: '1d'
}
// デコード
return new Promise((resolve, reject) => {
jwt.verify(idToken, PEM, opts, function(err, decoded) {
if (err) {
reject(err)
} else {
resolve(decoded)
}
})
})
}
const idToken = issueToken()
console.log(idToken)
const result = verifyToken(idToken)
console.log(result)

PHPでFirebase Cloud Messaging(FCM)のPush通知を送信する方法【Node.js】

■はじめに

Firebase Cloud Messaging(以降、FCM)でPush通知を送信するため、「Server Key」と、送信先の「Device Token」が取得できている前提として本手順を記載します。

■手順

以下に、PHPでFCMのプッシュ通知を送信する処理を記載します。

<?php
$api_key = "{サーバーキー}";
$base_url = "https://fcm.googleapis.com/fcm/send";
$data = array(
"to"           => $_POST['token']
, "priority"     => "high"
, "notification" => array(
"title" => $_POST['title']
, "body"  => $_POST['body']
, "sound" => "default"
, "badge" => $_POST['badge']
)
);
$header = array(
"Content-Type:application/json"
, "Authorization:key=".$api_key
);
$context = stream_context_create(array(
"http" => array(
'method' => 'POST'
, 'header' => implode("\r\n", $header)
, 'content'=> json_encode($data)
)
));
file_get_contents($base_url, false, $context);
echo "access";
?>

Node.jsでFirebase Cloud Messaging(FCM)のPush通知を送信する方法【Node.js】

■はじめに

Firebase Cloud Messaging(以降、FCM)でPush通知を送信するため、「Server Key」と、送信先の「Device Token」が取得できている前提として本手順を記載します。

■手順

Node.jsからFCMに対して、リクエストを送るために、以下のコマンドで、「request」のnpmモジュールをインストールする。

npm install request --save

FCMを送るために、「 https://fcm.googleapis.com/fcm/send 」に対してPOSTリクエストを行い、通知を送ります。

Bodyに通知の情報を設定する必要があります。

以下に、FCMの通知を送信する関数を記載します。

/**
* プッシュ通知送信処理
* @param {*} serverKey サーバーキー
* @param {*} deviceToken デバイストークン
* @param {*} title タイトル
* @param {*} message メッセージ
*/
function pushMessage(serverKey, deviceToken, title, message) {
var headers = {
'Content-Type': 'application/json',
'Authorization': 'key=' + serverKey
};
var dataString = '{"to": "' + deviceToken + '", "notification": {"title": "' + title + '", "body": "' + message + '", "sound": "default"}, "priority":"high"}';
var options = {
url: 'https://fcm.googleapis.com/fcm/send',
method: 'POST',
headers: headers,
body: dataString
};
request(options, callback);
}

上記の関数を呼び出す際には、以下のように呼び出します。

pushMessage({サーバーキー}, {デバイストークン}, {通知タイトル}, {通知内容});

以下が、呼び出しの例です。

pushMessage("AAAA6UEzuRA:APA91bFhX84Xyl-ZZZsssadasanogbeoasjnak0-21-4r1mfoas", "fLc3NGPOgsw:APasdagolrnaeiuiflaksdnlaiuhilab", "タイトル", "メッセージ");

PM2を利用してNode.jsのプロジェクトを実行する方法(npm start)【Node.js】

■はじめに

express-generatorを使用してNodeプロジェクト(ejs)を作成する方法」の記事で作成したNode.jsのプロジェクトを前提としています。

プロジェクトの作成方法がわからない場合は上記の記事をご参照ください。

■手順

1.以下のコマンドを実行して、PM2をグローバルにインストールする。

$ npm install -g pm2

2.以下のコマンドを実行して、アプリケーションを起動する。(「[アプリ名]」の箇所には自由にアプリ名を入力してください。PM2の管理で使用するアプリ名となります。)

$ pm2 start npm --name [アプリ名] -- start

■おまけ

・以下のコマンドを実行することで、起動しているPM2のアプリ一覧が確認できます。

$ pm2 list

・以下のコマンドを実行することで、対象アプリの停止ができます。

$ pm2 stop [プロセスID]

・以下のコマンドを実行することで、全てのアプリの停止ができます。

$ pm2 stop all

・以下のコマンドを実行することで、対象アプリの再起動ができます。

$ pm2 restart [プロセスID]

・以下のコマンドを実行することで、全てのアプリの再起動ができます。

$ pm2 restart all

express-generatorを使用してNodeプロジェクト(ejs)を作成する方法【Node.js】

■はじめに

本記事はNode.jsがインストールされている事が前提となります。

まだインストールされていない方は「ローカルにNode.jsをインストールする方法」の記事をご参考にインストールしてください。

■手順

1.以下のコマンドをターミナルで実行し、グローバルパッケージをアップデートする。

$ npm update --global

2.以下のコマンドをターミナルで実行し、「Express Generator」をグローバルインストールする。

$ npm install express-generator --global

3.以下のコマンドをターミナルで実行し、プロジェクトを作成したいディレクトリに移動する。

$ cd [ディレクトリパス]

4.以下のコマンドをターミナルで実行し、プロジェクトを作成する。

$ express appname --view=ejs

5.以下のコマンドをターミナルで実行し、プロジェクト内に移動する。

$ cd appname

6.以下のコマンドをターミナルで実行し、Nodeモジュールをインストールする。

$ npm install

7.以下のコマンドをターミナルで実行し、Nodeサーバーを起動する。

$ npm start

8.ブラウザで以下のURLにアクセスし、正常にアクセスできることを確認する。

http://localhost:3000/

■おまけ

・サーバーのアクセスポートを変更するには、「package.json」の「scripts」内を以下のように書き換えるだけでできます!(サーバーにアップして使用する際にはファイアーウォール に穴を開けるのをお忘れなく。)

"scripts": {
"start": "PORT=[ポート番号] node ./bin/www"
},

サーバー再起動時にPM2の状態を復元する方法(自動起動)【Node.js】

■はじめに

PM2を利用してNode.jsのプロジェクトを実行する方法(npm start)」の記事でPM2を利用したプロジェクトの実行方法を記載しました。

しかし、サーバーを再起動すると、起動しているNodeサーバーが停止されるようになります。

複数のプロジェクトを並行起動していた場合、それぞれ起動し直すのは手間なので、サーバー再起動時に自動起動させる方法を記載します。

■手順

1.以下のコマンドを実行しPM2のプロセスに起動されていることを確認する。

$ pm2 list

2.以下のコマンドを実行し、自動起動スクリプトを作成する。

$ pm2 startup

3.以下のコマンドを実行し、現在のPM2の状態を保存する。

$ pm2 save

4.サーバーを再起動し、以下のコマンド実行結果が「1」と同じであることを確認する。

$ pm2 list

CentOS7にnodebrewを使用してNode.jsをインストールする方法【Node.js】

■はじめに

CentOS7の環境構築はこの記事では記載しませんので、別途お調べください。。。

■手順

1.以下のコマンドを実行して、nodebrewをインストールする。

$ curl -L git.io/nodebrew | perl - setup

2.以下のコマンドを実行して、nodebrewのPATHを通す。

$ echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bashrc

3.以下のコマンドを実行して、「2」で設定したPATHを反映させる。

$ source ~/.bashrc

4.以下のコマンドを実行して、Node.jsを「安定版」でインストールする。

$ nodebrew install stable

5.以下のコマンドを実行して、Node.jsの「安定版」を利用するように反映する。

$ nodebrew use stable

■おまけ

以下のコマンドで、インストールできるNode.jsのバージョンが確認できます。

$ nodebrew ls-remote

上記で確認したバージョンを以下のようにコマンド実行することで、指定バージョンをインストールすることができます。(以下は「v12.5.0」をインストールする場合)

$ nodebrew install-binary v12.5.0

インストールしたら、バージョンを切り替える必要がありますので、以下のコマンドでバージョンを切り替えましょう。

$ nodebrew use v12.5.0

ちなみに、インストールしているNode.jsの全てのバージョンを確認したい場合は以下のコマンドです。

$ nodebrew ls