2013年11月21日木曜日

nodejsからPHPを実行してWordPressのユーザー認証

nodejs_wordpress-usernodejsを使ってiPhone, Androidアプリ用のRest APIを開発する際に、WordPressのデータベースを使ったユーザー認証をしたかったので調査。

環境: CentoOS 5.10, node.js 0.10.21, php 5.4.21

最初はPHPでやっていることをJavaScriptで再現しようとしたけど、ソースコードを読んで無理そうだと諦めた。

なので、nodejsからPHPを外部コマンドとして呼び出して返り値を受け取ることにした。

nodejsから外部コマンドを実行するのは"child_process"を使うらしい。

 

nodejsから実行するPHPファイル。

wp_checkpassword.php

<?php
/**
* WordPress Check Password for CommandLine
*
* @usage
*   # php wp_checkpassword.php --hash="hash" --password="password" --path="/path/to/wordpress"
*/

$options = getopt(null, array('hash:', 'password:', 'path:'));

//
// Validation
//
if (empty($options['hash']) ||
    empty($options['password']) ||
    empty($options['path'])) {
  exit('option error');
}


//
// @see wp-includes/pluggable.php line:1448
//
$check = false;
require_once($options['path'] . 'wp-includes/class-phpass.php');
// By default, use the portable hash from phpass
if ($wp_hasher = new PasswordHash(8, true)) {
  $check = $wp_hasher->CheckPassword($options['password'], $options['hash']);
}

echo json_encode($check);
?>

 

このPHPファイルを呼び出す側。

var command = [];
var process = require('child_process');
// Get the Password Hash from Database.
var user_pass = '$P$BpIMHINnR/9y.e90cMuY3Af0eIWZ6Z1';

command.push('php');
command.push('php/wp_checkpassword.php');
command.push('--hash="' + user_pass.replace(/\$/g, '\\$') + '"');
command.push('--password="' + pass + '"');
command.push('--path="' + config.wordpress.path + '"');

process.exec(command.join(' '), function (err, stdout, stderr) {
  stdout = JSON.parse(stdout);
  if (stdout) {
    console.log('Login Success!');
  }
});

「user_pass」はPOSTされたユーザーID(メールアドレス)からSQLを実行してwp_users.user_passを取得してくる必要あり。

取得したハッシュ値はそのままだと「$」の部分をLinuxのシェルが解釈してしまうのでエスケープする。

 

< 2014/01/07 Modified >
送信するパラメータをシングルクォーテーションで囲めば「$」をエスケープする必要はない。

command.push('--password=\'' + pass + '\'');

JSON.stringifyした値も渡せるので、こっちの方が良さそう。

 

応用すればWordPressの便利関数を使える。

新規ユーザー登録や新規投稿などはWordPressにパイプした方が楽かもしれない。でも値の受け渡し方法を考えないといけないか。。。

 

 

< Related Posts >

2013年11月12日火曜日

[Titanium Mobile]Performance改善のためApplicationの設計を見直す

performance_upAndroid, iPhoneアプリが一段落したので、次期開発に向けてアプリの設計とより良いパファーマンスを得られる書き方など調べ直したときの覚書。

環境:Titanium SDK 3.1.3.GA

まず公式ドキュメント

アプリのサンプルも公開されてた。

でもこれ2年間更新されてない(SDK v1.8.1)ので、abcsWriterの方がいいかも。

両方とも「名前付き関数(named function)」を多用しているので無名関数(nameless function, anonymous function)とどっちがいいか調査。

名前付き関数の方が速いらしい。

var hogeFunc = function() {};

このような無名関数を基本使っていたのでショック。今後は名前付きにしよう。。。

 

< 2013/11/20 Modified >

ChariTiというアプリが非常に参考になる。

lib/core.js, lib/http.js, utilities.jsとかヨダレが出そうになるぐらい。別記事で詳細を紹介する予定。

 


去年のCODESTRONG(カンファレンス)のビデオを見てみた。

今後気をつけること。

  • setterを使うよりプロパティでアクセスした方が速い
  • "透明"はコストが掛かるので常に背景色を設定した方が速い

 

関連した記事も見つけた。これは実際やってみる。

 


公式ドキュメントからリンクされてたこちらの記事はTitanium Mobile(CommonJS)におけるオブジェクト指向の記述方法をサンプルで分かりやすく解説している良記事。

 

余力があるなら下記記事もチェック

 

 


作ったアプリでメモリリークがないかチェックする方法

限られた開発期間の中でもチェックできるような体制にしたい。

 

< Related Posts >

2013年11月8日金曜日

携帯(スマフォ)2台持ちなら激安SIM月額490円がお得

ktai_smartphone_charge最近激安SIMがあることを知ったので、契約して使ってみた。

参考サイト

契約したのはこちら。

概要

  • 初期費用:3150円
  • 月額:490円
  • ドコモ回線
  • 回線最大速度100kbps(ドコモのXiは最大150Mbps)
  • 転送量制限なし
  • 高速化するオプション有り
  • 1年縛り、2年縛りとかがないので気軽に試せる

 

切り替える前のドコモ料金はこちら。

ガラケー(F-01C) 基本使用料
(FOMAタイプSS_バリュー)
+1年割り
+ファミリー割引
924円
ガラケー(F-01C) パケ・ホーダイ ダブル定額料 372円
スマフォ(Galaxy S2) 基本使用料
(Xiデータプランフラットにねん)
3791円
スマフォ(Galaxy S2) SPモード 300円

 

これをガラケー+激安SIMにすると

ガラケー(F-01C) 基本使用料
(FOMAタイプSS_バリュー)
+2年割り
924円
スマフォ(Galaxy S2) ServersMan SIM LTE 100 490円

 

単純計算で毎月3973円安くなる。

 

100kbpsでも通勤途中は録画して転送した動画を見ているので問題なし。体感的には「ちょっと遅いかな?」という程度。電車の中の繋がりにくさは同じ。

今度利用者数が増えると遅くなりそうな予感。。。

「Xiデータプランフラットにねん」の解約金1万円を払っても変更した方が断然お得。ただ自分のスマフォが他社のSIMに変更出来るかは要確認。

「パケ・ホーダイ ダブル定額料」を解約すると「Xiデータプランフラットにねん」が正規料金になってしまうので、月末(3日前ぐらいからOK)にドコモショップで手続きする必要がある

 

< 2013/11/28 Modified >
ドコモショップに行ってきたら解約当月は必ず「Xiデータプランフラットにねん」の正規料金を請求されるので、月末に行こうが関係ない。

日割りに出来ないので、新しいSIMカードが届いたらすぐ解約しても大丈夫。値段は変わらないので月末まで持っててもいいかも。

前の担当者は研修生だったので対応があやふや。やっぱり慣れている人だとサクサク話が進むので早い。

 

ServersMan SIMカードは申し込んでから届くまでに1週間掛かった。

 

導入のタイミングが遅すぎたドコモメール(@docomo.ne.jp)も使わない。

 

< Related Posts >

2013年11月7日木曜日

nginx + node.js + pm2でアプリ向けのREST API環境を構築

nginx_nodejs_pm2前回の記事でWeb APIについて勉強し、モバイルアプリからのリクエストはNode.jsで捌くことにした。そのために環境を構築したときの覚書。

環境:CentOS 5.10, Node.js 0.10.21, nginx 1.4.3, pm2 0.6.5

 

< 2014/05/30 Modified >
CentOS6版も書いたのでそちらも参考に。

 


1.Node.jsをインストール

< 2013/12/09 Modified >
本番環境の場合は実行ユーザーで作成した方がいいので、この記事の最後の方を参照。

前の記事を参考にnvmでインストールする。

# nvm install v0.10.21
# nvm alias default 0.10.21

 


2.「Hello World」を作成

プロジェクトディレクトリに移動
# cd /home/project/

ExpressというNode.js向けのフレームワークをベースにする。

restifyというREST Webサービス用に特化したモジュールもあるけど、開発のスピードと下記ベンチマークを参考にExpressを選択。

expressjsの公式ドキュメント通りに「Hello World」を作る。
# vi package.json

{
  "name": "hello-world",
  "description": "hello world test app",
  "version": "0.0.1",
  "private": true,
  "dependencies": {
    "express": "3.x"
  }
}

# npm install

# vi app.js

var express = require('express');
var app = express();

app.get('/', function(req, res){
  res.send('hello world');
});

app.listen(3000);

アプリ起動
# node app

別コンソールからアクセスして確認
# curl -i http://localhost:3000/

 


3.nginxを設定してブラウザから外部からアクセス

既にnginx + php-fpm + WordPressの環境があるので、リバースプロキシの設定をして外部から参照可能にする。

WordPressのサブディレクトリで動作させたかったので、ファイルが存在しなかったときのパーマリンクの動作を修正。

# vi /etc/nginx/conf.d/hoge.conf

server {
    listen       80;
    server_name  wordpress.hoge.net;

    ### Reverse Proxy for API
    location /api/ {
        rewrite ^/api/(.*)$ /$1 break;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_pass http://127.0.0.1:3000;
    }

    ### if the file is not found, forwarded to index.php (permalinks)
    set $rewrite_flg "false";
    if (!-e $request_filename) {
        set $rewrite_flg "true";
    }
    if ($uri ~ "^/api/") {
        set $rewrite_flg "false";
    }
    if ($rewrite_flg = "true") {
        rewrite ^/(.*)$ /index.php?q=$1 last;
    }
}

 

ブラウザからアクセスして確認
http://wordpress.hoge.net/api/

「hello world」が表示されるはず。

 


4.PM2をインストールしてnodeアプリをデーモン化

最後に常時起動させておくようにデーモン化する。

foreverよりpm2の方がクラスタリング(複数プロセスを使った負荷分散)も出来ておすすめらしい。

参考サイト

 

インストール
$ npm install -g pm2

すると下記エラー

gyp ERR! configure error
gyp ERR! stack Error: Python executable "python" is v2.4.3, which is not supported by gyp.
gyp ERR! stack You can pass the --python switch to point to Python >= v2.5.0 & < 3.0.0.

pythonのバージョンが古いらしい。メッセージにある通り「--python」オプションを利用してみる。

$ yum install python26
$ npm install -g pm2 --python=python26

起動する
$ pm2 start app.js -i max

Warningが出た。

PM2 [ERROR]  [Warning], you're using the 0.10.x node version, it's prefered that you switch to fork mode by adding the -x parameter.

node v0.10.xではstopしたときにポートを開放しないので、「fork mode」での動作がオススメらしい。詳しくは下記。

再起動
$ pm2 stop all
$ pm2 start app.js -x

動いているプロセスを表示
$ pm2 list

何が出来るかヘルプをみる
$ pm2 help

 

ファイルを監視して自動で再起動するのはまだ開発中ということなので、しばらくはnode-devを使って開発していた方がよさそう。

 

< 2013/12/09 Modified >
本番環境はrootで動かすと恐いのでnodejs実行用のユーザーを作成する。あとで権限の設定をするためにwwwというグループに所属させる。
# groupadd www
# useradd node -G www
# passwd node

所属グループの確認
# groups node

apacheユーザーの所属グループの変更
# usermod -G www apache

apacheユーザーだけが書き込み権限持っていた場所をwwwグループにも権限を与える
# chown apache.www -R /path/to/wordpress/wp-content/uploads
# chmod 775 -R /path/to/wordpress/wp-content/uploads

ユーザー切り替え
# su - node

ここからはnvmのインストールからやり直し。

ちなみにpm2は「-u」オプションで起動ユーザーを指定することができる。
$ pm2 -u apache start app.js -x

でもpm2で起動している場合「Permission denied」でファイルの書き込みに失敗する。node-devの場合は成功するのでまた今度調査。

 

< 2013/12/12 Modified >
nginx + php-fpmで動いている環境もuser=apche, group=wwwで動作するための設定を追記。(今まではuser=apche, group=apache)

php-fpmの設定
# vi /etc/php-fpm.d/www.conf

group = www

nginxの設定
# /etc/nginx/nginx.conf

user  apache www;

sessionの書き込みディレクトリの権限(/etc/php-fpm.d/www.confに記述)
# chown apache.www -R /var/lib/php/session/

※YUMでPHPが更新されたときに権限が変更されることがあったので注意。

phpMyAdminが下記エラーで起動しなくてハマった。

2013/12/12 18:44:47 [error] 3653#0: *188 readv() failed (104: Connection reset by peer) while reading upstream
2013/12/12 18:44:47 [error] 3653#0: *187 recv() failed (104: Connection reset by peer) while reading response header from upstream

念のためnginxのキャッシュディレクトリも権限を変更する
# chown apache.www -R /var/cache/nginx/*

 

< 2013/12/27 Modified >
接続元のIPアドレスを取得したかったので、X-Forwarded-Forの設定を追記。

 

 

< Related Posts >

2013年11月6日水曜日

iOSアプリをDistributeするときに120x120が必要になった

app-store_120x120iconTitanium Mobileで作成したアプリをストアに送信する「Validation」をしたときに下記エラーが出るようになった。

Missing recommended icon file - The bundle does not contain an app icon for iPhone / iPod Touch of exactly '120x120' pixels, in .png format.

120x120のアイコンが必要になったらしい。

環境: Titanium SDK 3.1.3.GA

参考にしたサイト。

 

上記サイトを参考に

  • Resources/iphone/appicon-60.png
  • Resources/iphone/appicon-60@2x.png

を用意したらValidationが通った。

 

< Related Posts >

Related Posts Plugin for WordPress, Blogger...

Blog Archives