君は心理学者なのか?

大学時代に心理学を専攻しなぜかプログラマになった、サイコ(心理学)プログラマかろてんの雑記。

JavaScriptのgetter, setterについて復習してみた

getter, setterとは

オブジェクトに値を代入したり、

参照したりする時に呼ばれる関数のこと。

書き方

set {プロパティ名}(value) {
  // 処理
}
get {プロパティ名}() {
  // 処理
}

のように書く

実例

var obj = {
    set value(val) {
        this._value = val + 1;
    },
    get value() {
        return 'getterからは' + this._value + 'を返す' 
    }
}
obj.value = 1; // setterが呼ばれる
console.log(obj.value); // getterからは2を返す ←getterが呼ばれている

用途

値をセットしたり、値を参照したりする時、

決まった処理をする際に便利。

json-serverが鬼のように便利で、しかも可愛かった

f:id:karoten512:20180512165110p:plain

いきさつ

APIのmockがほしかった。

今までexpressとかで実際にAPIをつくっていたのだが、

ちょっとめんどくさくなってきた。

何かいい方法がないかな〜と思ってたら「json-server」という良さげなものがあったので試してみた。

github.com

install

npm install -g json-server

jsonデータを用意

db.jsonというファイルを用意する。

{
  todos: [
    { id: 1, content: aaaa, done: false },
    { id: 2, content: bbb, done: true },
    { id: 3, content: ccc, done: true }
  ]
}

json-serverを起動

db.jsonというファイルを同ディレクトリ内に用意。

json-server --watch db.json

f:id:karoten512:20180512164253p:plain

絵文字がかわいい。

localhost:3000にアクセス

f:id:karoten512:20180512164428p:plain

こっちもかわいいかよ。

localhost:3000/todos/1 にアクセス

{
  "id": 1,
  "content": "aaaa",
  "done": false
}

しっかり返ってきてる。

まとめ

GETしか試していないが、

ドキュメントに

GET    /posts
GET    /posts/1
POST   /posts
PUT    /posts/1
PATCH  /posts/1
DELETE /posts/1

とあるのでいろいろ使えそう。

あとかわいい(重要)

【突然の沈黙】JavaScriptのobjectスプレッド演算子について

いきさつ

ソースコードを読んでいたら、

var arr = [1, 2, 3]
var arr2 = [4, 5, 6]
arr.push(...arr2)

とつぜん処理の中で沈黙(...)し始めた。

f:id:karoten512:20180511220526j:plain

気持ち悪かったので調べてみた。

ドキュメントを見てみる

スプレッド構文を使うと、関数呼び出しでは 0 個以上の引数として、 Array リテラルでは 0 個以上の要素として、 Object リテラルでは 0 個以上の key-value のペアとして、 Array や String などの iterable オブジェクトをその場で展開します。

うーん。

わかるようなわからんような。

実際に試してみよう。

...Array, ...Stringはどうなるのか

...Array だと

var arr = [1,2,3]
console.log(...arr) // 1 2 3

ばらばらになるイメージ?

...Stringだと

var str = 'hello world'
console.log(...str) // h e l l o   w o r l d

やはりばらばらになる。

ばらばらにしたものを、何かに渡してみる

関数呼出しに渡すその1

ためしに、...arrを3つの引数を受け取る関数に渡してみる。

var arr = [1, 2, 3]

function add(x, y, z) {
  return x + y + z
}

console.log(add(...arr)) // 6

なるほど。たしかに、

関数呼出しでは3つの引数として展開してくれている。

関数呼出しに渡すその2

この2つの配列をマージするケースを考えてみる。

var arr = [1,2,3]
var arr2 = [4,5,6]

arr.push(arr2)
console.log(arr) // [1, 2, 3, Array(3)]

普通にpushで書くとマージできない(当たり前だけど)

これじゃない。これがやりたいんじゃない。

ここで、

objectスプレッド演算子を使って展開した値を、

配列が持っている関数、pushに渡してみる。

var arr = [1,2,3]
var arr2 = [4,5,6]

arr.push(...arr2)
console.log(arr) // [1, 2, 3, 4, 5, 6]

おお。たしかに関数呼出し内で引数として展開されていることが確認できる。

なるほどねぇ。

配列に渡してみる

var str = 'hello world'
console.log([...str]) //  ["h", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d"]

おー。確かに配列内で要素として展開されている。

これでsplitを使わなくても良くなるな。

まとめ

objectスプレッド演算子を使うと「ばらばらになる」

そのばらばらになったものを、関数に渡したり配列に渡したり、

Objectに渡したり(まだ試してないけど)することにより、

処理の記述が簡単になる。

Vue.jsにて、特定のroutingの時に後からComponentを読み込む〜ログイン後にコンポーネントを読み込みたいからLazy Loadしてみた〜

いきさつ

ログイン前はログインコンポーネントだけ、

ログイン後はアプリケーションに必要なコンポーネントを読み込みたい。

目的は、

ログイン前に読み込むJavaScriptソースコードの軽量化と、

それによるセキュリティリスクの減少。

やりかた

はじめ、こんな感じだったとします。

import Vue from 'vue'              
import Router from 'vue-router'

/** ログイン画面で読み込むコンポーネント */
import Login from '@/components/Login'

/** ログイン後に読み込みたい(Lazy Load)したいコンポーネント */ 
import Index from '@/components/Index'

Vue.use(Router)

export default new Router({        
  routes: [                        
    {
      path: '/login',
      name: 'Login',          
      component: Login             
    },
    {
      path: '/',
      name: 'index',
      component: Index
    }
  ]
})

これを、下のようにするだけです。

import Vue from 'vue'              
import Router from 'vue-router'

/** ログイン画面で読み込むコンポーネント */
import Login from '@/components/Login'

/** ログイン後に読み込みたい(Lazy Load)したいコンポーネント */ 
const Index = function () {
  return import('@/components/index')
}

// 後は同じ

importとreturn importの違いですが、

import Index from '@/components/Index'

とすると、Indexにはオブジェクトが入り、

const Index = function () {
  return import('@/components/index')
}

とすると、__webpack_requireという関数が入るようです。

ログイン後webpack_requireが実行され、その際にソースが読み込まれる感じ。

結果

f:id:karoten512:20180511004137g:plain

ログインボタンを押した後、

1.jsというファイルがあとから読み込まれている事が確認できます。

この1.jsにはindexコンポーネントの情報が入っていました。

Vue.jsでComponentを利用する〜templateのみ〜

f:id:karoten512:20180510000333p:plain

いきさつ

職場でVueを使うので勉強する必要がある。

とりあえず

vue-cliを使っても良いが、

きちんと理解したいので生で書くことにした。

ルートコンポーネント

<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue TEST</title>
</head>
<body>

<div id="app">
  <my-component></my-component>
</div>

<script src="./vue.js"></script>
<script src="./app.js"></script>
</body>
</html>

ここでいうid="app"のdivで囲まれている部分がVueで管理される範囲。

今回はmy-componentタグで囲まれている部分をComponentとして、

Vueで管理してみる。

テンプレート情報だけをもつコンポーネントを作ってみる

// app.js
// コンポーネントの定義            
var mycomponent = {                
  template: '<div>hello</div>'     
};

// コンポーネントの登録
Vue.component('my-component', mycomponent);

// 今後生成されるすべてのvueインスタンスで使えるようになる
var app = new Vue({
  el: '#app'
});

component自体はタダのオブジェクト。

templateというkeyにcomponentのhtml構造をもたせることができる。

そして、

Vue.component('my-component', mycomponent);

でVue(のコンストラクタ)にcomponentを登録する。

この宣言をしておくと、

今後生成されるすべてのVueインスタンス内において、

mycomponentが使えるようになる。

まとめ

すごい単純。

メリットはhtml構造が使い回せるくらい。

Componentが増えたり処理が増えたりすると、Componentを単一ファイルで管理する

「単一ファイルコンポーネント」ということになってくる。

イスラーム過激派のハッカーが知人のサーバをハッキング。マルウェアが6000個検出された話

f:id:karoten512:20180506181832p:plain

いきさつ

知人のサイト(WordPress)が見れなくなったということで、

とりあえずsshでログインしてみた。

とりあえず調査

探し方としてはかなり荒っぽいけど、とりあえず

phpファイルのうち、evalを含むファイルを検索した。

find . -type f -name "*.php" | xargs grep 'eval'

あった。

あったというか滅茶苦茶あった。

カウントしてみる。

find . -type f -name "*.php" | xargs grep 'eval' | wc -l
6000

えぇー。

いったん応急処置

あまりサイトが見られない時間が長いのはSEO的にヤバイ(メディア系なので)。

いったんマルウェアを削除して再アップし、

その後にログ調査などして根本原因を突き止めることにした。

マルウェア削除 軌跡

ファイルを調べてみると

3月10日に生成されているファイルがほとんどだった。

(念のため日付はぼかしてあります)

そこをハッキングされた日として、

一旦一週間前の3月3日以降に生成された怪しいファイルを、

どんどん消していくことにした。

find . -type f -name "*.php" -newermt "2018-03-03"

を元に、

怪しい文字列を含むファイルを検出、中を確認しながら順番に削除していく。

(すごい古典的な方法だから絶対もっといい方法があるはず)

どんなファイルがあったか

以下の3つに分けられた。

webshell系

f:id:karoten512:20180506183356p:plain

webshellってのはざっくりいうと、

webブラウザからシェルを使えるようにするやつ。

ファイルの転送、実行、編集、削除、

シェルコマンドの実行など、シェルでできそうなものならなんでもできる感じ。

DBにアクセスしたりすることもできる。

これが置かれたらサーバに対してだいたいなんでもできる。

非常に厄介。

これが1000個くらい。

なぜか3種類くらいのwebshellが置かれていた。そんなにいる?

メーラー

サーバからスパムメールを送ることができるツール。

leafmailerというphpで作られた有名なツールが置かれていた。

これが3000個くらい。

自己誇示系

Hacked by ***

みたいに、自分のハンドルネーム的なファイルを書き残している。

これが2000個くらい。

とりあえず怪しいファイルは全部消した

結局3月10日以降に作られたファイルは全部マルウェア系だった。

攻撃者のプロファイル

ファイル名や、Hacked by *** から、攻撃者のプロファイルが何となく想像付いた。

攻撃者はおそらく、

イスラーム過激派

か、

それを騙った愉快犯っぽい。

ファイル名で検索するとそれっぽい写真がいっぱい出てくる。

どちらにしても迷惑だな。手当たり次第かよ。

脆弱性を突き止めるために

現在、ハッカーさんがアクセスログを残してくれているっぽいので解析中。

ログ残してくれてるあたり、あまりプロの仕事ではないんだろうなぁ。

優秀な人は、ログを改ざんしたり削除したりしていくらしいけど。。。

まとめ

ハッキングされると後が大変。。。やめてほしい。。

ファイルのタイムスタンプを保持したまま、scpコマンドで転送する

f:id:karoten512:20180506162850j:plain

いきさつ

サーバからファイルをダウンロードした後、

日付情報を用いてファイル処理をする必要があった。

コマンド

scpコマンドにpオプションを付けるだけ。

scp -rp remote_host:remote_dir local_dir

ちなみに

ファイル転送時に新しく作られるディレクトリについては、

どうしても転送時のタイムスタンプになるっぽい。