OmniAICreator/Qiita-1.07M huggingface dataset:
CTF解法メモ【Hacker101】

# これは？
CTFを解く中であまりにも自分ができなさすぎるので，そもそも当たり前としてどこにも載っていないレベルの常識を書き溜めるモノ．Hacker101の問題を取り上げる



適宜更新していく

## micro-cms v1: Easy


### 解けなかったやつ
* URLに対するSQLi -> `/path/to/10'`
    * １時間考えても全く思いつかず
* ただの気づきがないやつ -> `閲覧URLのパーミッション拒否ページを見たあと，その編集ページは開ける`
    * `/path/to/10` は403だが `/path/to/edit/10` は見れてフラグがある
    * そもそも番号が一部飛んでることに気付けなかったのが問題

### 解けたやつ
* `'javascript'`が消される環境下でのxss
    *  -> `onclick='alert(1)'`, `<iframe src='base64encoded alert'>`
    *  とかそこらへんがある！

## micro-cms v2
* こいつには編集と追加のためにログインをしなければいけなくなった


### 解けたやつ

* エディット画面に行こうとすると，リダイレクトがかかるが，実は直接リクエストを投げるといけちゃう
    * `curl -X POST 'http://url/page/edit/1' -d 'title=1&body=1'`

### 解けなかったやつ

* ログイン処理にはSQLiがある．
    * 試しにユーザの入力欄に`'`を入れる
        * `if cur.execute('SELECT password FROM admins WHERE username=\'%s\'' % request.form['username'].replace('%', '%%')) == 0:`
        * こいつが見えるので，適当にUNIONしてみるらしい（こいつができなかった，思いつくやつ天才か？）
    * payload -> `' UNION SELECT '123' as password#`
    * 結果として`SELECT password FROM admins WHERE username='' UNION SELECT '123' as password#`が実行される
    * こいつで，パスワードに`123`が追加されるため，１２３を入力しログインをバイパス出来る．

* ログインパスをリスト型攻撃するらしい
    * WriteUp見ても全く意味がわからず？？？？
    * 答えを見ても解けていない．

## Photo-Gallery: Moderate

### 思考記録

* url query paramをそのままSQLに組み立てて居るので，SQLiが可能である．
* `?id=1` が正常にレスポンスし， `?id=1 union select 2;--` も正常であったため，SQLiが可能と判断
* `?id=1 union select 1 order by filename desc;--` が正常だった
    * `filename`というカラムがある．
    * `asc` 指定でソートするとエラーが出る．
        * すなわち，以下のような処理フローで画像を返すAPIを実装していると想定

```
id = url.param["id"]
↓
filenames = sql.exec("SELECT filename from table_name where id = ${id}")
↓
imgname = filenames[0]
↓
data = readFile(imgname)
↓
response.body(data)

```


        * order句により，辞書順にソートされるため逐次チェックすると，ファイル名がわかる．
        * `"files/adorable.jpg"` `"files/purrfect.jpg"`というファイル名だった
        * →で？
【Windows】AWS CLI のインストールと設定手順（Python＆pip使用）

Windows PCに、Pythonとpipを使用し、AWS CLI をインストールする方法です。

###対象ツール
AWS CLI

###前提条件
端末：Windows PC
Pythonインストール済

###手順
####1. インストール
**①pythonのバージョンの確認**
・python3が入っていればOK（以下はpython 3.7.3）

```
> python -V
Python 3.7.3　
```

**②pipを使用して、AWS CLI をインストール**
・以下を実行

```
> pip3 install awscli
```
**③パスの確認**
・以下を実行

```
> where c:\ aws
```
・見つからない場合は、以下を実行する

```
> where /R c:\ aws
```

**④Pathの設定**
・Windowsボタンを押して検索ボックスで「環境変数」と入力して検索し、
　3で表示されたPathを設定する

【例】表示結果が「c:[userdirectory]\Python\Python37\Scripts\aws」の場合
　**設定内容：c:[userdirectory]\Python\Python37\Scripts**

**⑤AWS CLIのバージョンの確認**
・インストール、Pathの設定が正常であれば以下のような結果が出力される

```
> aws --version
aws-cli/1.16.225 Python/3.7.3 Windows/10 botocore/1.12.215
```
**※注意点：環境変数設定前からコマンドプロンプトが起動していた場合は一度閉じて、再度立ち上げる**

####2. 設定
**①IAMユーザーのアクセスキーの作成**
・[Identity and Access Management (IAM)](https://console.aws.amazon.com/iam/)にアクセス
・左側のAWS Accountペインより、「ユーザー」をクリック
・「認証情報」 > 「アクセスキーの作成」
・「.csvファイルのダウンロード」をクリック（キー情報を得る）
・accessKeys.csvがダウンロードされ、キー情報が得られる

**※注意点：accessKeys.csvは紛失しないようにすること**


**②かんたん設定（一般的な使用の場合）**
・コマンドプロンプトにて、以下を実行

```
> aws configure
```
AWS Access Key ID, Secret access key, Default region name, Default output formatが順に問われるので、以下を参考に設定

```
> AWS Access Key ID [None]：csvファイルのAccess key IDを入力
> Secret access key:csvファイルのSecret access keyを入力
> Default region name [None]: ap-northeast-1
> Default output format [None]:json
```

**※補足1：Default region nameは[AWS Service Endpoints](https://docs.aws.amazon.com/general/latest/gr/rande.html)を参照。ap-northeast-1はAsia Pacific (Tokyo)**
**※補足2：Default output formatのデフォルトはjson**

###参考
[CLI の使用 | AWSドキュメント](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Tools.CLI.html)
[Windows に AWS CLI をインストールする | AWSドキュメント](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-windows.html)
[]()
mkdir + touch を実現するコマンドinstall

※このコマンドは`touch`の副次的機能である空ファイルの作成を行います。
存在しているファイルを第2引数に指定すると空ファイルとなってしまうのでご注意ください。

```
install -D /dev/null test/hoge.txt
```

## それぞれの説明
- `install SRC DEST`: SRCをDESTにコピーする
- `install -D SRC DIR/DEST`: DIRディレクトリを作成し、SRCをDIR/DESTにコピーする
- `/dev/null`:

> /dev/null は通常、プロセスの不要な出力ストリームを捨てるのに使うか、入力ストリームのための空のファイルとして使う。

今回は後者の空ファイルとして扱っている


## 参考ページ
https://ja.wikipedia.org/wiki//dev/null
https://linux.die.net/man/1/install
Pythonで言語判定をする[pycld2]

# pycld2インストール
OSはUbuntuで行っていますが、
Windowsの場合、適切なコンパイラがない場合はVC++のコンパイラを用意する必要があるようです
(面倒なので私は未実施)


```bash

git clone http://github.com/abosamoor/pycld2.git
cd pycld2
sudo python3 ./setup.py install

# もしpython.h云々のエラーが出たら適宜このあたりをインストール
sudo apt-get install python2.7-dev
sudo apt-get install python3-dev


```

# 言語判定の一例
英語かどうかを判定するとき。

```python
isReliable, textBytesFound, details = cld2.detect("This is a pen.")
if "en" == details[0][1]:
    print("英語です！")
```


# 参考
[pycld2 0.31](https://pypi.org/project/pycld2/)
box-sizing:border-box;

box-sizing:border-boxは実務で使用すべきなのか気になって調べてみましたが、
ググると超便利という記事ばかりが出てきました。
デフォルトの値で設定しておいてもＯＫレベルみたいです(^^)

参考記事は、以下の記事です♪
http://phiary.me/css3-box-sizing/

デフォルト値を変えちゃうことをオススメしていました! 

サイトを作る際, 必ずリセットスタイルに下記の 指定を加えているそうです.

```html
*, *:before, *:after {
    -webkit-box-sizing: border-box;
       -moz-box-sizing: border-box;
         -o-box-sizing: border-box;
        -ms-box-sizing: border-box;
            box-sizing: border-box;
}
```

あとは、サルワカさんの以下の記事もとてもわかりやすいですね(^^)
いつもありがとうございます。
https://saruwakakun.com/html-css/reference/box-sizing
JetBrains IDEを使っている人は、JetBrains Toolbox Appがおすすめ！

IntelliJ IDEAや、PyCharmやWebStorm、Riderなど、JetBrains社のIDEを使っているならば、`JetBrains Toolbox App`を導入することをおすすめします！

`JetBrains Toolbox App`は、各種JetBrains社のIDEのインストール、アンインストール、設定などの管理を行えるアプリです。

[公式ブログ](https://www.jetbrains.com/toolbox/)

![スクリーンショット 2019-09-01 16.56.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4125/5893d714-7d27-0732-e531-a41c09cafecd.png)

`JetBrains Toolbox App`で以下のようなことが楽に行えます！

* 各種IDEの起動が楽！
* アップデートがあるかの確認ができる、アップデート自体も！
* アンインストールも楽！
* 最新版と安定版など複数バージョンの同時インストール・管理が楽
* 前のバージョンに戻すのも楽！
* EAP(Early Access Program)やRC(Release Candidate)が気軽に試せる
* 複数のIDE（例えば、WebStormとRider）を使う場合の管理が楽

JetBrains社のIDEを使っているならば、

「別に安定板or最新版だけしか使わないし・・・」
「別に一つのIDEだけしか使わないし・・・」

って人も、導入することをオススメします！

* [公式ブログ](https://www.jetbrains.com/toolbox/)
* [JetBrains Toolbox App(Samuraism社のブログ)](https://samuraism.com/jetbrains/jetbrains-toolbox-app)
* [便利なJetBrains Toolbox App、お使いですか？(JetBrains日本語ブログ)](https://blog.jetbrains.com/jp/2018/10/09/1294)
OWASP ZAP CLI 入門(インストール、起動方法、基本的なオプション)

## これはなに

![6716868.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/3e2a0695-9051-7be3-b171-226c64e207e1.png)

OWASP ZAPをCLI(CUI) から起動する方法と代表的なオプションを紹介します。

## はじめに

OWASP ZAPの入門者向けの情報です。
私自身、ZAP初心者である為、内容がふわっとしていたり、想像の域をでなかったり、受け売りだったりするのでご了承ください。


## 脆弱性診断ええんやで(^^)

本記事は、[脆弱性診断研究会](https://security-testing.doorkeeper.jp/)が主催する「脆弱性診断ええんやで(^^)」という勉強会に参加して学んだ内容を元に作成しています。

講師は、EGセキュアソリューションズ株式会社の松本隆則さん@nilfigoです。
(参加させていただき、ありがとうございました)

> 脆弱性診断研究会（Security Testing Workshop）は、Webアプリケーションやネットワーク機器などに対する脆弱性診断の手法や診断ツールの使用法を研究するコミュニティです。


本勉強会は、基本は月に一度開催されており、３ヶ月に一度、脆弱性診断ビギナー向けとして開催しているそうです。


※本記事の内容に不都合があれば、すぐに削除します。


## OWASPとは

https://www.owasp.org/index.php/Japan

> OWASP - Open Web Application Security Project とは、Webをはじめとするソフトウェアのセキュリティ環境の現状、またセキュアなソフトウェア開発を促進する技術・プロセスに関する情報共有と普及啓発を目的としたプロフェッショナルの集まる、オープンソース・ソフトウェアコミュニティです。The OWASP Foundationは、NPO団体として全世界のOWASPの活動を支えています。

## OWASP ZAP（オワスプ・ザップ）とは

ZAPは、無料のセキュリティ診断用プロキシツールです。
https://github.com/zaproxy/zaproxy

- ZAP: Zed Attack Proxyの略
- Zed:究極な という意味
- オープンソース Apache License 2.0

脆弱性診断のプロの方曰く、業務でZAPを使う事はあまりないとのことですが、
「無料にしてはよくできてる」とのこと。
プロの方は`Burp Suite`などの有料ツールを使うらしいです。

## OWAPS ZAPのインストール方法

ZAPはZAPの公式Githubリポジトリからダウンロードできます。

https://github.com/zaproxy/zaproxy/wiki/Downloads

<img width="876" alt="スクリーンショット 2019-09-01 16.07.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/15432c57-e5ea-20a4-02d6-7828fea0a9b4.png">

Macの方はBrew Caskでお手軽インストールできます

```
brew cask install owasp-zap
```

## OWASP ZAPの起動

OWASP ZAPを起動するとGUIが表示されます。

<img width="1048" alt="スクリーンショット 2019-09-01 16.11.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/fd93720e-48da-1e0c-6556-6913026b3153.png">

## OWASP ZAPのモードについての注意

デフォルトでは`標準モード`となっていますが、`プロテクトモード`に変更することを推奨します。

`通常モード`では、調査対象に設定したサイト(コンテキスト)以外について、ZAPから攻撃用のリクエストが送信されてしまう恐れがあります。
その場合、第三者のサーバに大量のリクエストが送信されてしまい、法に触れる恐れがありますので十分に注意してください。

`プロテクトモード`では、コンテキスト以外に攻撃用のリクエストが送られる事がないので安心です。

<img width="336" alt="スクリーンショット 2019-09-01 16.12.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/56c65147-0a5e-05ba-86f2-ead2e402d388.png">


## CLIによるOWASP ZAPの起動方法

CLIによる起動方法もGithubリポジトリのWikiに書いてあります。

https://github.com/zaproxy/zap-core-help/wiki/HelpCmdline

Mac OSでは、以下でZAPが起動します。

```
/Applications/OWASP\ ZAP.app/Contents/Java/zap.sh
```

オプションなしで実行すると、GUIが起動すると思います。

## OWAPS ZAPのコマンドラインオプション

勉強会で教えていただいた、基本的なオプションを紹介します。

| Option | 説明 |
|---|---|
| -daemon |UIなしで起動|
| -dir <dir>　|作業ディレクトリ|
| -newsession <path>|ZAPセッションの保存先|
| -host　<host> |ZAPの待受IPアドレス指定|
| -post　<port> | ZAPの待受ポート指定|


これらのコマンドがあれば、GUIなしで起動ができ、
実行毎に作業ファイルの保存先を変えたり、
ポートやホストを変えて多重起動することも可能です。

### コマンドラインオプション利用の例

```
/Applications/OWASP\ ZAP.app/Contents/Java/zap.sh -daemon -port 54321
```


##まとめ

- OWASP ZAPは無料のセキュリティ診断用プロキシツール
- ZAP CLIはコマンドラインでZAPを起動する方法
- CUIにより起動できれば、診断やレポート出力の自動化など夢が広がる

以上、お役に立てば幸いです。
WebViewでBasic認証ができない

# はじめに
Chrome Custom Tabsが登場して早数年、WebView使うのか、CCT使うのか、はたまたブラウザに飛ばすのか。
いろいろ議論があるところではありますが、CCT使うとブラウザにキャッシュが残っちゃってログインしっぱなしになるからWebView使って解決できないかな！？という流れになったことからWebViewでBasic認証しようと実装を直してみたところBasic認証でけへんやんけ！？という状況に出くわし、調査に数日を費やして無駄にしたことから自戒の念を込めて記録を残すものである。

# 3行でまとめると
* 参考にしたサイトの実装は出来る限りそのまま採用しよう
* framework内部で何が行われているかよーく確認しよう
* [OpenGrok](https://sites.google.com/site/devcollaboration/codesearch)は偉大

# 対象バージョン
* Android 6.0.1

# どんな実装をしていたか
WebViewClientを継承したHogeClient的なものの中で以下のように実装していた。
たぶんわかる人にはすでに問題点がわかると思います。

```kotlin
override fun onReceiveHttpRequest(
    view: WebView?, handler: HttpAuthHandler?, host: String?, realm: String?) {
    super.onReceiveHttpRequest(view, handler, host, realm)
    /* usernameとpassword取得する処理 */
    handler?.proceed(username, password)
}
```

# 参考にしたサイト
* https://re-engines.com/2019/03/27/android-webview-tips-2/
* https://codeday.me/jp/qa/20190225/302768.html

# なにが悪かったのか
この記事を書いている時点でOpenGrokのソースコードのページにアクセスできなかったので[GitHub](https://github.com/aosp-mirror/platform_frameworks_base/blob/e80b45506501815061b079dcb10bf87443bd385d/core/java/android/webkit/WebViewClient.java)のリンクを用意しておきます。

```java
     /**
      * Notifies the host application that the WebView received an HTTP
      * authentication request. The host application can use the supplied
      * {@link HttpAuthHandler} to set the WebView's response to the request.
      * The default behavior is to cancel the request.
      * 
      * @param view the WebView that is initiating the callback
      * @param handler the HttpAuthHandler used to set the WebView's response
      * @param host the host requiring authentication
      * @param realm the realm for which authentication is required
      * @see WebView#getHttpAuthUsernamePassword
      */
     public void onReceivedHttpAuthRequest(WebView view,
             HttpAuthHandler handler, String host, String realm) {
         handler.cancel();
     }
```
おわかりいただけただろうか…
そう、onReveiveHttpAuthRequest()のsuper呼んだ時点で詰んでいたのです。
ソースのコメントに書いてあるということは、[Android Developersのdoc](https://developer.android.com/reference/android/webkit/WebViewClient.html#onReceivedHttpAuthRequest(android.webkit.WebView,%20android.webkit.HttpAuthHandler,%20java.lang.String,%20java.lang.String))にも書いてあるのでは…
`The default behavior is to cancel the request.(デフォルトの動作は、リクエストをキャンセルすることです。)`
書いてあるやん！
そして前述の参考にしたサイトを見てみるとやはりsuperを呼んでいない。
ライフサイクルでsuperを呼ぶことが癖づいていたことと、overrideする際に自動で付加されていたために起こった不幸だということにしたい今日この頃です。
なお、Android studioでonReceiveHttpAuthRequestに飛んでみると以下のようになっているので気づけません。(なんかおかしいぞ？とはなるかもしれませんが)

```java
    public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
        throw new RuntimeException("Stub!");
    }
```

# 終わりに
基本アプリ開発中心になると大多数のエンジニアはAndroidのframeworkを見ることはほとんどないかなと思うのですが、過去にAndroid端末開発(工場向けアプリからframework改造あたりまで)をしていたこともあり、OpenGrokの存在を知っていたことからframeworkの実装を調べてみてようやく己の間違いに気づけました。
なお、そもそも調べようとしていたのはHttpAuthHandlerのproceedだったので原因の箇所を見たのは奇跡でした。
Angularのテンプレート内で script タグを読み込む方法

Angularのテンプレート内ではクロスサイトスクリプティングを防ぐためにscriptタグが使えません。

Angular内でscriptタグが必要になった場合の方法を紹介します。

本記事は参考として、charjsを読み込んでみます。

#方法1

参考にしたサイト
http://kenteiblog.hatenablog.com/entry/2018/08/25/113644

一つ目の方法は、Angularのテンプレートが読み込まれた後に動的にscriptタグを追加する方法です。

componentのAfterViewInitメソッド内で動的にscriptタグを作成し、属性を埋め込んでテンプレートに追加します。

```typescript:load-script.ts

ngAfterViewInit() {
    const script = document.createElement('script');
    script.async = true;
    script.src = 'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.4/Chart.min.js';

    const div = document.getElementById('script');
    div.insertAdjacentElement('afterend', script);
}
```

テンプレートはこのようになっています。

```html:load-script.component.html
<div id="script"></div>
```

idで要素を取得して、その後ろにscriptタグを追加しています。

#方法2

参考サイト
https://stackoverflow.com/questions/42458346/need-to-insert-script-tag-in-angular-2

続いては、コンポーネントをスクリプトの読み込み専用にする方法です。

同じくAftetViewInitの中でscriptタグを作成してテンプレートに埋め込みます。

```typescript:script-tag.ts
ngAfterViewInit() {

    const element = this.script.nativeElement;

    const script = document.createElement('script');
    script.type = this.type ? this.type : 'text/javascript';

    if(this.src) {
      script.src = this.src;
    }

    const parent = element.parentElement;
    parent.parentElement.replaceChild(script, parent);
  }
```

テンプレートはこのようになっています。

```html:script-tag.component.html
<div #script style.display="none"></div>
```

このコンポーネントを呼び出す時に、セレクタにsrcとして任意のurlを渡すことができます。

```html:app.component.html
<script-tag src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.4/Chart.min.js"></script-tag>
```

私個人的には方法2の方が使いやすいですが、そもそもAngularからscriptを読み込みたくなる時ってそんなにない気がする。。。
VSCode + Remote-Container + linux で CodeCommit にHTTPS接続したときにエラーが出る場合の対処

VSCode + Remote-Container + linux (私はamazonlinux2を使用) という開発環境で
CodeCommit にHTTPS接続しようとしたときにNullReferenceExceptionが出てしまう場合の対処

# 原因
codecommitを使う場合、ヘルパの記載を ~/.gitconfigにしていると思いますが
/usr/etc/gitconfig
このファイルがあると~/.gitconfigのcredential.helper が無視されます。

[2019/10/19追記]
VSCodeのバージョンが変わったのか今は/etc/gitconfigにファイルが生成されるようです。

```config:/usr/etc/gitconfig
[credential]
  helper = "!f() { command -v code >/dev/null 2>&1 && code --gitCredential $*; }; f"
```

VSCodeからコンテナ起動するたびに再作成されるようなので
~/.bashrc に以下記載をすることで毎回削除するようにしました。

```bash:~/.bashrc
if [ -e /usr/etc/gitconfig ];then
  rm /usr/etc/gitconfig
fi
```
ここにcodecommitのhelperの設定を書き込んでもいいかもしれません。

役にたった人はいいねください！
なるべくわかりやすいJavaScript

# はじめに
最近(対して最近でもない)、angurar.js、react.js、vue.jsなど、
JavaScriptのフレームワーク・ライブラリが人気を博しております。

フロントエンド(ブラウザ)だけではなく、バックエンドでも使えるようになり活躍の場が広がりました。
SPA(Single Page Application)の流行もあって、
様々な現場で扱う機会の増えたJavaScript。

今回は自分の復習も兼ねてJavaScriptの基礎を綴っていこうと思います！

# JavaScriptで出来ること
JavaScriptを使うことによって動きのあるWEBサイトを作ることが出来ます。
例を少しあげましょう。

- 確定ボタンをクリックしたら確認のポップアップが表示される
- フォームに入力したら入力文字数が表示される

ごく一例ではありますがこのように、
**「〇〇を〇〇したら〇〇させる」**
ということができるのがJavaScriptです！

# もう少しエンジニアっぽく言い換える
**「〇〇を〇〇したら〇〇させる」**

これをもう少しエンジニアっぽい言葉に置き換えてみましょう。

- 〇〇を(**ノード**)
- 〇〇したら(**イベント**)
- 〇〇させる(**関数**)

**「対象のノード(DOM)に対してイベントが実行されたら関数を実行させる」**

というようなイメージでしょうかね！

# JavaScriptを書いてみよう！
というわけで、
ここからはそれぞれに対して具体的にどんな記述をしていくのか説明していきます！
例として**ボタンがクリックされたらアラートを表示する**というものをやってみましょう！

因みにHTMLは以下の通りです。

``` html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8"/>
  <title>なるべくわかりやすいJavaScript</title>
</head>
<body>
  <button id="btn">押したらアラートを表示</button>
  <script>
    // ここにJavaScriptを書く
  </script>
</body>
</html>
```

表示させるとボタンがぽつんとある画面ですね。シンプル。
<img width="282" alt="無題.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188440/62b8b570-3148-9cb6-4f72-9d5750ee7337.png">

## ノードを取得する
まず初めに**ノード**を取得しましょう。
詳しくは説明しませんが、ノードというのは**DOMと呼ばれる仕組みの中における要素**の事をさし、それに対してイベントを設定したり、関数を適用させることで動きのあるWEBサイトにできます。
**JavaScriptの動作のきっかけとするオブジェクト**と考えてもらえればよいと思います！

では実際にノード取得してみます。

``` html
<script>
  const btn = document.querySelector("#btn");
</script>
```

この一行だけでノード取得が可能です！便利！
今回はquerySelectorというAPIを使用していますが、`getElementById`でも問題ありません！

### 参考
- [querySelectorについて](https://developer.mozilla.org/ja/docs/Web/API/Document/querySelector)
- [getElementByIdについて](https://developer.mozilla.org/ja/docs/Web/API/Document/getElementById)

## イベントを登録する
では続いて**〇〇したら**に該当するイベント登録を行います。
今回はイベントリスナを使ってみましょう！

``` html
<script>
  const btn = document.querySelector("#btn");

  btn.addEventListener("click", /*関数名/, false);
</script>
```

これで**クリックしたら関数実行**という紐付けが完了しました！
簡単ですね！

イベントリスナ以外にもいくつかイベント登録する方法が用意されています。
HTMLタグに記述できる**イベントハンドラ**、
ノードに設定できる**イベントプロパティ**など。

個人的には記述が区別でき、複数イベントを登録できるイベントリスナが好みですが、
現場、メンバーによって異なると思いますので知っておいて損はありません！

### 参考
- [イベントリスナについて](https://developer.mozilla.org/ja/docs/Web/API/EventTarget/addEventListener)
- [イベントハンドラについて](http://phpjavascriptroom.com/?t=js&p=event)
- [イベントプロパティについて](http://phpjavascriptroom.com/?t=js&p=event_object)

## 関数を作る
それでは最後に関数を書きましょう！

``` html
<script>
  const btn = document.querySelector("#btn");

  function viewAlert(e) {
    alert("アラートです");
  }

  btn.addEventListener("click", viewAlert, false);
</script>
```
**アラートを表示させる関数`viewAlert`を実装し、
`addEventListener`の第二関数に関数名を記述すればOKです。**
簡単すぎる…！！

ここまでをコピペしたらボタンをクリックしてみてください。
アラートが表示されるはずです！

関数についてはメインロジックを書くので慣れが必要です。
が、慣れれば逆にメインロジックだけを書けばいいので整理もしやすいと思います！

## 最後に
いかがでしたでしょうか！？

バラバラに考えると記述の役割が異なるので理解しやすいのではないかと思います！

ご指摘等あればコメントをお願いいたします！
最後までお読みいただきありがとうございましたー！

またどこかでお会いしましょう！
既存ディレクトリにgit cloneして上書きしようとしたら叱られたので、別の手順で上書き(忘備録)

まだgitで管理されていないローカルの「$HOME/foo」ディレクトリに、ソースコードとデータが保存されているとします。
別の誰かによってリモートリポジトリが新規作成され、最新のソースコードがアップされました。
データはバージョン管理の対象にしないため、リモートリポジトリに含まれないとします。
ローカルの「$HOME/foo」配下に古いソースコードとデータを置いたまま、git clone foo.git してリモートの最新ソースコードで上書きしようとしたら．．．

```
fatal: destination path 'foo' already exists and is not an empty directory.
```

上記のように叱られました。
そこで、git cloneに代わる手順を試しましたので、以下に記します。

```
# 既存ディレクトリに移動（古いソースコードとデータあり）
cd $HOME/foo

# 空のローカルリポジトリを作成
git init

# リモートリポジトリを追加
git remote add origin https://XXXXX/foo.git

# 最新のソースコードを、リモートブランチから追跡ブランチに持ってくる
git fetch origin master

# 1回目のブランチ確認
git branch -a

# 追跡ブランチのソースコードで、ローカルブランチのソースコードを強制上書き
git reset --hard origin/master

# 2回目のブランチ確認
git branch -a

# HEAD設定
git remote set-head origin master

# 3回目のブランチ確認
git branch -a
```

以上の手順で、バージョン管理の対象にしないデータを残したまま、ローカルのソースコードをリモートの最新で上書きできました。

1回目のブランチ確認では、以下のように表示されました。

```
  remotes/origin/master
```

2回目のブランチ確認では、以下のように表示されました。

```
* master
  remotes/origin/master
```

3回目のブランチ確認では、以下のように表示されました。

```
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
```

## 参考ページ
[git pull で、ローカルを強制上書きする方法](http://www-creators.com/archives/1097)
[Gitのリモートブランチと追跡ブランチは違うよ](https://www.kaeruspoon.net/articles/1078)
[gitのHEAD(ローカルスタート)](https://qiita.com/tsuyoshi_cho/items/8bca5ee3576da82cbba6)
セキュリティ入門


#主な攻撃方法と対策
##攻撃の種類
|種類|手法|
|---|---|
|Webアプリケーションの脆弱性をついた攻撃|・SQLインジェクション<br>・OSコマンドインジェクション<br>・クロスサイトスクリプティング<br>・クロスサイトフォージェリ|<br>・サーバーサイドリクエストフォージェリ(SSRF)
|上記以外|・標的型攻撃<br>・ランサムフェア<br>・DoS攻撃<br>・ポートスキャン<br>・DNSキャッシュポイズニング|

###SQLインジェクション
・データベース処理の脆弱性をついた攻撃。
・Webサイトの入力フィールドにSQLコマンドを入力することでデータベース内部の情報を不正に操作する。

###OSコマンドインジェクション
・Webサイトの入力フィールドにOSコマンドを入力することで内部の情報を不正に操作する。

###クロスサイトスクリプティング(XSS)
・Webページの出力処理の脆弱性をついた攻撃
・悪意のあるスクリプトがユーザ環境で実行されることで、入力した個人情報などが盗み出される。

###クロスサイトフォージェリ(CSRF)
・正規なリクエストがどうかの判定を行なっていないサイトへの攻撃
・外部サイト経由のリクエストが実行され、意図しない処理が実行される。

###サーバーサイドリクエストフォージェリ(SSRF)
・サーバーが持つ権限・認証を利用して不正な命令を実行する攻撃

[リクエストフォージェリ – SSRFとCSRF](https://blog.ohgaki.net/request-forgery-ssrf-and-csrf#SSRFCSRF)

###ランサムフェア
・PCやサーバーのデータを暗号化し、復旧するための金銭を要求する攻撃

###DoS攻撃
・大量の通信を発生させ、CPUやメモリに過負荷をかけ、サーバーをダウンさせるなどしてサービスを妨害する攻撃(pingコマンドなどが使われる)
※攻撃用のサーバーをC&C(Command & Control)サーバーという。C&Cサーバーにbotを作って攻撃するケースが多い。

###標的型攻撃
・官公庁や企業などの特定の組織の情報を狙って行われる攻撃のこと
・標的となった組織に対して、取引先や社内関係者になりすました偽装メールを送信し、ウイルスを仕込んだ添付ファイルの実行やWebサイトへのアクセスを誘導され、機密情報を盗まれる。

###DNSキャッシュポイズニング
・キャッシュが汚染されたDNSサーバーによって、悪意のあるサーバーに誘導され、機密情報を盗まれる。
※DNSサーバーの挙動として、ホスト名とIPアドレスの対応tableが格納されているが、毎回対応tableを参照しているわけではなく、処理速度を早めるために一度読み込んだ内容はキャッシュに格納されている。そのキャッシュ情報をhackする攻撃手法がDNSキャッシュポイズニング
DNS＝ホスト名とIPアドレスを対応させる仕組み

##ネットワークセキュリティ対策
- IDS(Intrusion Detection System) 不正侵入検知｜IPアドレス、ポート番号をチェック
- IPS(Intrusion Prevention) 不正侵入防御｜データ量やふるまいをチェック
- WAF(Web Application Firewall)｜入力されたデータをチェック

![スクリーンショット 2019-09-01 11.59.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374557/7ee83b50-6aa2-a266-c554-e7a55b68f787.png)

#暗号化と認証
##暗号化
・データを規則に従った変換し、第三者が解読できないようにすること

##暗号化方式
###共通鍵暗号方式
暗号化と復号に同じ鍵を使用する。
暗号化と復号の処理は高速だが、鍵の配送を安全に行う仕組みが必要になる。
暗号化のアルゴリズムにはDES→AESがある。
※DES→AES｜DESで脆弱性が見つかったため、AESにUpdateされた。

###公開鍵暗号方式
暗号化と復号で異なる鍵を使用し、暗号化する鍵(公開鍵)を公開し、復号する鍵(公開鍵)を秘密にする。
暗号化と復号の処理が複雑なため処理に時間がかかるが、鍵の配送や管理が容易。暗号化のアルゴリズムにはRSAがある。

##認証
・データやユーザーの正当性を証明する技術
・メッセージを送信したのが本人であることや、内容が改ざんされていないことを証明することで、ネットワークを介した情報のやり取りの完全性を高めている。
代表的な認証技術｜
　・デジタル署名
　・HTTPS｜http通信にSSL/TLSの技術を追加したもの
　・SSL(Secure Sockets Layer)

デジタル署名の仕組み

###デジタル署名
・公開鍵暗号方式とハッシュ関数を組み合わせた技術(認証アルゴリズム｜SHA-1、SHA-256、MD5など)
・デジタル署名を利用することで、送られたデータに改ざんがないことと、送信者が正しいことを証明する。
ハッシュ関数｜データを数値化するための計算式
AWS APIのアップデートの際に確認した記録｜CloudFront API

Amazon CloudFront - Update on Older API Versionsというタイトルの
メールが届き内容を確認してみるとどうやらcloudfrontAPIのバージョンが上がるとのこと。
そして一部の機能が廃止になるという趣旨の内容を確認しました。

#今回のメールの内容をざっくりと
そもそもSDK内の関数でcloudfront設定を操作していたりしなければ関連はない。
AWS CLIのcloudfrontを操作するようなものが今回のAPIに相当する。

#参考ページ
対応方法を調査してみると以下のページを見つけました。
https://aws.amazon.com/jp/premiumsupport/knowledge-center/cloudfront-api-version-check/

#調査の概要
自分のケースだとcloudfrontのcookie認証を使用しており
S3にログを保存している状態でした。
このcloudfrontのログをcloudtrailにて管理
それをAthenaからSQL文にて検証（検索）し
cloudfrontAPIの古いバージョンが使用されていないかを確認する
という内容で以下詳細を書いていきます。

#cloudtrailが有効か確認します
cloudtrailコンソール画面にてバージニアリージョンを選択。
cloudtrailが有効かを確認します。まだ使用したことがないようだったら以下のページを参考に有効に設定をします。
https://docs.aws.amazon.com/ja_jp/awscloudtrail/latest/userguide/cloudtrail-getting-started.html

#cloudtrailにてtableを作成
s3にcloudtrailのログが書き込まれたら
cloudtrailコンソールからtableを作成します。
https://docs.aws.amazon.com/ja_jp/athena/latest/ug/cloudtrail-logs.html#create-cloudtrail-table-ct

#AthenaからSQLを叩きAPIバージョンを検索する
参考ページのソースから引用

```serchver.sql

SELECT apiversion, count() AS Total FROM $databaseName.$tableName WHERE eventsource = 'cloudfront.amazonaws.com' AND parse_datetime(apiversion, 'yyyy_MM_dd') <= parse_datetime('2015_12_22', 'yyyy_MM_dd') GROUP BY apiversion ORDER BY Total Desc;
```

ここで\$databaseName.$tableNameを書き換えるとあるが
これはAthenaコンソール画面の左メニューに出ているものに書き換える。リージョンが違うと出てこないので注意が必要。

自分の場合はdefaultというデータベース名にcloudtrailで設定したテーブル名が出てきていたので
それらに書き換えて実行してみたところ
Zero records retumed
と表示されたので古いバージョンはないことが確認できた。

この時もし古いバージョンが見つかった際にさらに詳細を調べることもできるとのこと
そのSQL文は以下

```serchdetails.sql

SELECT useridentity.arn, sourceipaddress, eventname, useragent FROM $databaseName.$tableName WHERE eventsource = 'cloudfront.amazonaws.com' AND parse_datetime(apiversion, 'yyyy_MM_dd') <= parse_datetime('2015_12_22', 'yyyy_MM_dd');

```
USDJPYのバックテスト環境構築＠Jupyter

# やったこと
- USDJPYの1分足過去データの入手
- 入手したデータの読み込み
- 日付列と時刻列から日時データを作成
- ボリンジャーバンドの計算、描画

# USDJPYの1分足過去データの入手

[FOREX TESTER](https://forextester.jp/data/datasources, "FOREX TESTER")さんが公開しているデータをローカルに落としてきます。
ちなみに私は、USDJPY_test.txtというファイル名にしました。

【データ概要】
・時間足：　　　1分足
・データ期間：　2001年1月 - 2019年07月31日　※随時変わるかも知れません
・格納データ：　通貨ペア名, 日付, 時刻, 始値, 高値, 底値, 終値, 取引量

# 入手したデータの読み込み
ダウンロードしたデータを、pandas DataFrame形式で読み込みます。

```python
import pandas as pd

#オリジナルのデータ形式
#TICKER, DATE, TIME, OPEN, HIGH, LOW, CLOSE, VOL
df = pd.read_csv('USDJPY_test.txt', dtype={1:str, 2:str})
```
pd.read_csvの第2引数 dtype={1:str, 2:str} は、
　「読み込むデータの1、2列目※をstr形式で読み込みなさい」
という意味です。
　※最左列を0列目とカウントするため、ここでは「日付」「時刻」の列を指しています。

これをする意味は、後ほど「日付」と「時刻」から「日時」列を作成する際に、文字列の方が都合が良いからです。
なお、この処理を行わなければ、「日付」「時刻」列とも、numpy.int64型になってしまいます。

# 日付列と時刻列から日時データを作成
DATE列とTIME列からdatetime64型のデータを作り、DATETIME列として格納します。
完了後は、DATE列、TIME列ともに不要なので削除しました。

TICKER列も特に使用しなさそうなので、このタイミングで削除しています。

```python
#DATE列とTIME列からDATETIME列を作成し、dfのindexにする
df['DATETIME'] = pd.to_datetime(df['DATE'] + ' ' + df['TIME'])
df = df.set_index('DATETIME')
df = df.drop(['DATE', 'TIME'], axis=1)

#TICKER 列を削除
del df['TICKER']
```


# ボリンジャーバンドの計算、描画
ここまでで、過去データを分析する環境が整いました。
試しに、ボリンジャーバンドを計算し、グラフ化してみます。

```python
#計算
base = pd.Series.rolling(df['CLOSE'], window=25).mean() #直近25本の移動平均線
deviation = 2
sigma = pd.Series.rolling(df['CLOSE'], window=25).std(ddof=0) #σの計算
upper_sigma = base + sigma
upper2_sigma = base + sigma * deviation
lower_sigma = base - sigma
lower2_sigma = base - sigma * deviation

#描画してみる
d = '2001-1-3 10'
base[d].plot(label="base")
upper_sigma[d].plot(label="+σ")
upper2_sigma[d].plot(label="+2σ")
lower_sigma[d].plot(label="-σ")
lower2_sigma[d].plot(label="-2σ")
plt.grid()
plt.legend()

plt.savefig('Bollinger.png')
```

描画結果です。
![Bollinger.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490230/260997d7-07dd-cb84-09ba-9b4f7e52c822.png)


# まとめ
Pythonを使ってUSDJPYの自動売買アルゴリズムを開発するのがゴールですが、その前段のデータ入手について今回整理しました。

約19年分の過去データが使える形になったので、これを使って今後分析していきたいと思います。

また、ゆくゆくはJupyter環境構築方法など、Pythonを触れるようにするためのお膳立て部分についてもまとめていけたらと思います。
Local環境でLINE Botを開発するためのセットアップ

# 概要

この記事ではLocal環境でLINE Botを開発するために必要な手順を記載しています。

# 今回の内容

- LINE Developersの登録とチャネルの作成
- ngrokのインストール
- Webhook URLの設定

# 手順

## チャネルを作成する

以下のLINE Developers公式サイトの手順を参考にBot用のチャネルを作成します。
https://developers.line.me/ja/docs/messaging-api/getting-started

作成したチャネルを選択し、`Messaging API設定`タブ内にあるチャネルアクセストークンの「再発行」ボタンをクリックします。
<img width="1680" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490709/43b0c4b1-84c2-5271-9136-5a8542084314.png">

「アクセストークンを再発行しますか？」というダイアログが表示されますが、そのまま「再発行」をクリックすると、アクセストークンが発行されます。このトークンはMessaging APIの呼び出し時に必要になります。

## ngrokのインストール
ターミナルもしくはコマンドプロンプトから以下のコマンドを実行してngrokをインストールします。

```shell
# macの場合
brew cask install ngrok
# linuxの場合
npm i -g ngrok
```

Windowsもしくは、上記コマンドでインストールできない場合は、下記ngrok公式サイトを参考にセットアップしてください。アカウント登録も必要となります。
https://ngrok.com/download

次に、ngrokを起動します。

```shell
ngrok http 5000
```

以下のような結果が返ってくるので、Forwardingの前部分（下記の例では `http://7c4d4d83.ngrok.io`)をコピーします。

```shell
ngrok by @inconshreveable                                                                                         (Ctrl+C to quit)
                                                                                                                                  
Session Status                online                                                                                              
Session Expires               7 hours, 58 minutes                                                                                 
Version                       2.3.34                                                                                              
Region                        United States (us)                                                                                  
Web Interface                 http://127.0.0.1:4040                                                                               
Forwarding                    http://7c4d4d83.ngrok.io -> http://localhost:5000                                                   
Forwarding                    https://7c4d4d83.ngrok.io -> http://localhost:5000                                                  
                                                                                                                                  
Connections                   ttl     opn     rt1     rt5     p50     p90                                                         
                              0       0       0.00    0.00    0.00    0.00   
```

## Webhook URLの設定
先ほど作成したLINE Developersの`Messaging API設定`内の`Webhook設定`に移動し、Webhook URLに先ほどコピーしたURL(`http://7c4d4d83.ngrok.io`) + `/callback`を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490709/f1b55025-3982-8826-d41a-7cf5b9eb1f1e.png)

もしWebhookの利用がOFFになっていたら、トグルをONに切り替えてください。

以上でセットアップは終わりです。
sqlite3がbundle installできない！！

##問題点
本番環境でデプロイしてる最終にbundle installした時sqlite3のとこでエラーがでる:frowning2:

```エラー文.

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

current directory:
/home/ec2-user/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/sqlite3-1.4.1/ext/sqlite3
/home/ec2-user/.rbenv/versions/2.5.3/bin/ruby -r ./siteconf20190901-9332-hmjopf.rb
extconf.rb
checking for sqlite3.h... no
sqlite3.h is missing. Try 'brew install sqlite3',
'yum install sqlite-devel' or 'apt-get install libsqlite3-dev'
and check your shared library search path (the
location where your sqlite3 shared library is located).
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
        --with-opt-dir
        --without-opt-dir
        --with-opt-include
        --without-opt-include=${opt-dir}/include
        --with-opt-lib
        --without-opt-lib=${opt-dir}/lib
        --with-make-prog
        --without-make-prog
        --srcdir=.
        --curdir
        --ruby=/home/ec2-user/.rbenv/versions/2.5.3/bin/$(RUBY_BASE_NAME)
        --with-sqlcipher
        --without-sqlcipher
        --with-sqlite3-config
        --without-sqlite3-config
        --with-pkg-config
        --without-pkg-config
        --with-sqlcipher
        --without-sqlcipher
        --with-sqlite3-dir
        --without-sqlite3-dir
        --with-sqlite3-include
        --without-sqlite3-include=${sqlite3-dir}/include
        --with-sqlite3-lib
        --without-sqlite3-lib=${sqlite3-dir}/lib

To see why this extension failed to compile, please check the mkmf.log which can be
found here:

/home/ec2-user/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/extensions/x86_64-linux/2.5.0-static/sqlite3-1.4.1/mkmf.log

extconf failed, exit code 1

Gem files will remain installed in
/home/ec2-user/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/sqlite3-1.4.1 for
inspection.
Results logged to
/home/ec2-user/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/extensions/x86_64-linux/2.5.0-static/sqlite3-1.4.1/gem_make.out

An error occurred while installing sqlite3 (1.4.1), and Bundler cannot
continue.
Make sure that `gem install sqlite3 -v '1.4.1' --source 'https://rubygems.org/'`
succeeds before bundling.

In Gemfile:
  sqlite3
```

###解決策
本番環境のターミナルで`sudo yum install -y sqlite sqlite-devel`
してから`bundle install`
見積のやり方

最近、物忘れが激しくなってきて、具体的なことを思い出すのに時間がかかる（笑）

なので、具体的なことをメモっておく。

# 前提の考え方
規模によって、正確性が大きく変わる
規模が大きくなれば、正確に見積もるというのは、困難。
ただ、適当過ぎるのもダメ。

なので、考え過ぎず、考えなさすぎず、がポイント。

# 注意点
- 見積もる機能とフェーズに漏れが無いか？  
  要するに、工数が大きく変わる要素に漏れが無いか？
- バッファは、機能ごと、フェーズごとにバッファを盛らず、最後にバッファを考える  
  何故かと言うと、WBSを引く際に楽になります。  
  基本、実工数で線を引いて、バッファをXX人日分、載せる等調整がし易くなります。
- 工数の理由を大切に。  
  見積は、個人の主観になりがちなので、必ず第三者に見て貰う必要があります。  
  その際に理由を説明できるようにしておくのが大切です。  
  後は、お客さんにも説明しますので。
- 見積り前提を忘れずに。見積りしていない機能は、やらないが当たり前と思いますがら、明確にこの機能はやりませんと。書くことが大切。何故なら、お客さんも、忘れていて、あ！ってなり、再見積もりとかも発生するので（笑）

# やる事
## 規模が大きい（数十の画面、バッチ、APIとかがある）場合
なんちゃって、FP法になりますが、

1. 見積もる機能の洗い出し
2. 見積もるフェーズの洗い出し
3. 機能ごとに、難易度（簡単、普通、難しい）を決める。
4. 決める際には、簡単な理由、難しい理由をメモっておく。
5. 一通り難易度を決めたら、最初と最後で、難易度の先入観が変わってる可能性があるため、一通り再度見直す。
6. 「簡単には割り振った機能」を見て、「簡単は、何人日」、「普通は、何人日」、「難しいは、何人日」と決めて、工数を弾いていきます。
7. バッファで諸々調整します。

で、最後に、見積レビューをして他者の意見を貰って、調整という感じですかね。

## 規模が小さい（1個か、2個のバッチ、画面、APIとかの改修）場合

1. 要件定義、基本設計、実装、単体、結合、システムテストで、細かに見積もる。
2. バッファで諸々調整します。

で、最後に、見積レビューをして他者の意見を貰って、調整という感じですかね。

# 現場によりますが
上記で出して、過去の類似工数があればそれと比較し、バッファを調整します。
## 過去との比較で注意すること
メンバーによって、大きく工数が変わります。
なので、その当時のメンバーがどうだったのか？を改めて思い起こしつつ、比較する必要があります。

# 駄文
意外と記事を書いてみると、詰まります。
あれ？これどうしてたっけ？とか。
言語化することは、本当に大切ですね。
SSLサーバ証明書

##SSL/TLSとは
######SSL（Secure Sockets Layer）/TLS（Transport Layer Security）
インターネット上の通信を暗号化する技術。
第三者の盗聴や改ざんを防止し、ウェブサイトから入力する個人情報や
クレジットカード情報などのデータを安全にやりとりできる。

TLSはSSLの次世代バージョン。
SSLは仕様上の脆弱性が存在するためTLSに移行している。
現行のバージョンはTLS1.3

######主なプロトコル
https　　443　　htttp　　 80
smtps　　465　　smtp　　　25


##SSLサーバ証明書
情報を暗号化するSSLの機能に加え、ウェブサイトを運営する会社の身元を確認できる機能を備えた電子証明書。
一般的にSSLの呼称が広く普及しているため「TLSサーバ証明書」ではなくSSLサーバ証明書と呼ばれることが多い。


##暗号化の仕組み
①SSL/TLSを導入するサーバで「公開鍵」と「秘密鍵」を生成。
②SSLサーバ証明書に「公開鍵」を添付。
③ウェブサイト訪問者のPCにサーバから「SSLサーバ証明書」を送信。
④PCは「SSLサーバ証明書」に問題ないことを確認。
⑤PCは「SSLサーバ証明書」に含まれる「公開鍵」を利用して自分の「共通鍵」を暗号化してサーバに送信。
⑥サーバは「秘密鍵」を使って「共通鍵」を解読。
⑦以降、PCとサーバは「共通鍵」を使って通信。

※SSLサーバ証明書に問題がないかの確認。
　・正しい認証極から発行されているか
　・今通信しているサーバが、証明書に記載されているサーバと一致しているか
※SSLサーバ証明書には有効期限があり、期限切れの場合は警告画面が表示される。
※秘密鍵の漏洩などで証明書が失効された場合も警告画面が表示される。


##SSLサーバ証明書の種類

######ドメイン認証（DV：Domain Validation）
	ドメインに登録されている登録者を確認することにより、発行される。
	ドメイン名が正しいかどうかを認証する。
	低コスト。

######実在証明型（OV：Organization Validation）
	ドメインに加えWebサイトを運営している組織の実在性を証明する。
	ドメイン名に加え、会社名も証明する。
	サイト運営の成りすましを防止できる。

######実在証明拡張型（EV：Extended Validation）
	企業の実在性に加えて、所在地の認証を行う。
	法的・物理的に組織の実在性を確認して発行される。
	アドレスバーが緑色になり、組織情報が表示されるようになる。
	中間者攻撃を防止できる。ワイルドカード証明書が利用不可。


######ワイルドカード証明書：同一階層のサブドメインを1枚の証明書でまとめてSSL化できる。
		　　　通常はサブドメインの数だけ証明書が必要。

証明書の種類によって暗号化強度の違いはない。
個人情報を扱うようなサイトはOVまたはEVが最適。
Githubのアカウント名の変更方法

## GitHubのアカウント名の変更方法
アカウント名を適当につけてしまった時の変更方法です。

    1. GitHubのページでアカウントのアイコンをクリック
    2. Settingをクリック
    3. 左側のタブのAccountをクリック
    4. Change usernameボタンをクリック
    5. 警告メッセージが出てくるので、承認ボタンをクリック
    6. 任意のユーザ名を入れて完了ボタンをクリック
**※ユーザ名ではなく、アカウント名の変更方法です**
**※アカウント名を変更するとリポジトリのＵＲＬも変更されます。**
【JavaScript】フォーム入力中に'-'を自動で追加する（めも）

郵便番号を入力するとき、ハイフンが自動挿入された方が親切かな。
と言うことで、入力中に自動で'-(ハイフン)'入れる機能を試してみました。
その時のメモです。

こちらも間違っているなどあれば指摘いただけると嬉しいです！

# 郵便番号の入力フォームイメージ

完成イメージです。
こんな感じで4桁目に'-'ハイフンを入力したい。
![郵便番号.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445937/46e5017d-c75a-5d65-f287-937066aa01e9.png)

# コードサンプル
実際に仕込んだjsは↓のとおり。

```sample.js

$(function(){

  //郵便番号にハイフンを自動挿入するメソッド
  function insertStr(input){
    return input.slice(0, 3) + '-' + input.slice(3,input.length);
  }

  //入力時に郵便番号に自動でハイフンを付けるイベント
  $("#user_address_attributes_postal_code").on('keyup',function(e){
    var input = $(this).val();

    //削除キーではハイフン追加処理が働かないように制御（8がBackspace、46がDelete)
    var key = event.keyCode || event.charCode;
    if( key == 8 || key == 46 ){
      return false;
    }

    //３桁目に値が入ったら発動
    if(input.length === 3){
      $(this).val(insertStr(input));
    }
  });

  //フォーカスが外れた際、本当に4桁目に'-'がついているかチェック。なければ挿入するイベント
  //これでコピペした場合にも反応できるハズ？
  $("#user_address_attributes_postal_code").on('blur',function(e){
    var input = $(this).val();

    //４桁目が'-(ハイフン)’かどうかをチェックし、違ったら挿入
    if(input.length >= 3 && input.substr(3,1) !== '-'){
      $(this).val(insertStr(input));
    }
  });
}

```

```sample.html.haml
= fields.text_field :postal_code, class:'xxxx', placeholder:'例) 123-4567',maxlength:'8'
```

html側で桁数指定してあげると親切かと。

クレジットカードも何となく行けそうかな。
Payjpのまとめをする時に合わせてメモしようかと思います。

以上

# 参考
「[JavaScript] 文字列の指定位置に文字を挿入・削除する」
　: https://javascript.programmer-reference.com/js-string-insert/
「javascript – “入力”イベントのバックスペースとデルを検出しますか？」
　: https://codeday.me/jp/qa/20181223/81200.html
「押したキーのキーコードを取得」
　: http://shanabrian.com/web/javascript/keycode.php
docker間のAPIアクセス(for Mac)


# フロントdockerとAPIdocker間のアクセスをする方法

例えば、nuxtとRESTAPIを使って開発をしたい場合、githubのリポジトリをフロントとAPIで分けると思います。

## リポジトリ
- front-dockerリポジトリ(nuxtでフロントのみを実装）
- api-dockerリポジトリ(PHPやrubyなどバックエンド側のみを実装)


## 前提
api-dockerが `localhost:10000/api` で起動しているとして`localhost:10000/api`を叩けばレスポンスが返ってくる状態とします。


# api-dockerのエンドポイント

### :skull: BAD

これだと、nuxt(front-docker)からapi(api-docker)に `localhost:10000/api` ではアクセスできません。

```
localhost:10000/api
```
※ nuxtがdockerじゃない場合はこれでOK


### :tada: GOOD

docker同士のアクセスなので、`localhost`の部分を `http://docker.for.mac.localhost` にする必要があります。

```
http://docker.for.mac.localhost/api
```



# Proxyの設定

次にProxyの設定です。上記だけだとCORS(Cross-Origin Resource Sharing)で怒られます。

環境ごとにAPIのエンドポイントはかわるのでcross-envでenvファイルを用意しておく

```
$ yarn add cross-env
```

```:config/env.development.ts
module.exports = {
  API_HOST: 'http://docker.for.mac.localhost',
}
```

## @nuxtjs/proxyをインストール

```
$ yarn add @nuxtjs/proxy
```

## nuxt.config.tsに追記

```:nuxt.config.ts

const envSet = require(`./config/env.${environment}.ts`)
const API_HOST = envSet.API_HOST

const config: NuxtConfiguration = {
  ...省略
  
  modules: [
    '@nuxtjs/axios',
    '@nuxtjs/proxy'
  ],
  /*
   ** Axios module configuration
   ** See https://axios.nuxtjs.org/options
   */
  axios: {
    proxy: true
  },
  proxy: {
    '/api': {
      target: `${API_HOST}`,
      changeOrigin: true,
      pathRewrite: {
        '^/api/': '/api/'
      }
    }
  }

  ...省略
}
```
PHP クラスのプロパティ(メンバ変数)を連想配列に変換する

クラスのプロパティを連想配列に変換したいことがあったので備忘録です。

```php
<?php

class Sample
{
    protected $test2 = 'bbb';
    public $test3 = 'ccc';
    private $test1 = 'aaa';
    const TEST4 = 'ddd';
    public static $test4 = 'eee';
    protected static $test5 = 'fff';
    private static $test6 = 'ggg';

    public function getAttributes(): array
    {
        $data = [];
        foreach ($this as $key => $value) {
            $data[$key] = $value;
        }

        return $data;
    }

    public function toArray(): array
    { 
        return (array) $this;
    }

    public function getVariables(): array
    {   
        return get_object_vars($this);
    }  
}

$sample = new Sample();

// ①
print_r($sample->getAttributes());
// ②
print_r($sample->toArray());
// ③
print_r(get_object_vars($sample));
// ④
print_r($sample->getVariables());
```

## 実行結果

```shell-session
$ php Sample.php
// ① の結果

Array
(
    [test2] => bbb
    [test3] => ccc
    [test1] => aaa
)

// ② の結果

Array
(
    [*test2] => bbb
    [test3] => ccc
    [Sampletest1] => aaa
)

// ③ の結果

Array
(
    [test3] => ccc
)

// ④ の結果

Array
(
    [test2] => bbb
    [test3] => ccc
    [test1] => aaa
)
```

### ② の補足

`$this` は配列にキャストできます。 
ただし、その際にプロパティの分類に応じて、プロパティ名(配列キー)の前に特定のデータが付加されます。
publicプロパティ名は変更されません。
protectedプロパティには、「*」が先頭に付きます。
privateプロパティの先頭には、クラス名が先頭が付きます。

### ③, ④ の補足

`get_object_vars(object $object): array` は、指定した `$object` について、
そのスコープ内でアクセス可能な非staticプロパティを取得します。

## 参考

- [php.net プロパティ](https://www.php.net/manual/ja/language.oop5.properties.php)
- [php.net get_object_vars](https://www.php.net/manual/ja/function.get-object-vars.php)
プログラミング初心者がまず最初にやるべき5つのこと

　自分がプログラミングをはじめた頃、最初は右も左もわからず手当たり次第に書籍を読んだり、手を動かしていたりしたのですが、だいぶまわり道をしてきたように感じます。

しばらくたって最初からこれをやっておけば良かったというものがいくつもあったのでここで共有したいと思います。

ものすごく宗教戦争が起こりそうなテーマではありますが、あくまで個人の意見ですので、ご容赦を。
###  Progateを始める
 今の自分なら、真っ先にProgateをはじめると思います。

Progateはコンピューターサイエンスとはどんなものなのか雰囲気を説明することにものすごく長けているサービスであると感じます。

オススメルート
1.HTML&CSSコース
2.Rubyコース
3.Command Lineコース
4.Ruby on Rails5コース

これらによって次のステップであるRailsチュートリアルをはじめるために必要となる最低限の基礎知識を準備することができます。

個人的にProgateの中で一番よくできているなと感じるのが4のRuby on Rails5コースです。

しかし、このレッスンはProgateの中でもっとも分量が多く、根気のいるものです。

なので途中で挫折してしまっても気落ちしないでください。

またしばらく休憩してから再びはじめれば良いと思います。

###  Railsチュートリアルを始める

Railsチュートリアルは実際の開発現場でやるような実践的な方法でWebサービス開発を教えてくれるチュートリアルです。

これはProgateのRuby on Rails5 コースよりも難易度が高く、時間もかかります。

なので、少しずつ取り組んで行けば良いでしょう。
###  Githubのアカウントを作る

Railsチュートリアルと平行してやることになると思うのが、Githubによるソースコード管理です。

これはチーム開発で必須のものですが個人でサービス開発を使う場合にも使うことになると思います。

これにより自分の書いたソースコード を安全に管理することができるようになります。

Railsチュートリアル内で使うことになるのでやりながら覚えて行きましょう。

また、最近では企業の採用でGithubアカウントでどのくらいコミットをしているのかが重視項目になっていたりします。

###  オリジナルのWebサービスを作る

これも大事です。ProgateやRailsチュートリアルでは、指示通りコーディングしていくのですが、実際に開発をしていく際には自分のアイデアをコード に落としこんでいく必要があります。

この自分のアイデアをコード に落とし込むという過程は自分で実際に何かを作っていかないことには訓練していくことはできません。

なのでどんなに簡単なアプリでも良いのでまずは作ってみましょう。

オリジナルのアプリを作ることは簡単ではありません。非常に長い時間がかかるでしょう。

しかし、休憩しながら少しずつ作っていけば良いのです。

手間がかかる分完成したときの喜びはひとしおです。

そして、完成すればそれはポートフォリオになり転職や就職の際に大きなアピールポイントとなります。
###  Qiitaのアカウントを作る
Qiitaで自分の学びを共有することです。

これはオリジナルのWebサービスを作る次のステップというより同時にやって欲しいことです。

オリジナルのWebサービスを作っていると必ず何度も壁にぶち当たります。

その際に時間をかけて解決することになるわけですが、そのとき得られたTipsをQiitaで共有します。

また自分のWebサービスを作り上げるまでに自分の時間を全て捧げたとしてもおそらく通常であれば2,3ヶ月かかってしまうでしょう。

その間自分の成果が世に出ることはまったく無い訳です。

しかし、Qiita等で自分の得た学びを共有すれば少なくとも自分と同じステップでつまずいている人の役にたつ可能性があります。

そうなれば仮に途中で自分のWebサービスを作ることに挫折した場合でもそのときの悩み苦しんだ時間は決して無駄にはならないからです。

さらに最近では採用の際にQiitaのアカウントを要求する企業も増えてきています。

###終わりに
先日プログラミングを志したばかりで何をしたら良いか悩んで居る方にお会いしました。そこで、そのような方のお役に立てればと思います。
Nuxt.jsでreset.cssを使う

`assets/css/reset.css` にどこかからコピーしてくる。

グローバルに読み込みたいcssは `nuxt.config.js` に書くだけ。

```js

/*
 ** Global CSS
 */
css: [
  '~/assets/css/reset.css'
],
```

公式ドキュメントにも書いてありますね。
https://ja.nuxtjs.org/api/configuration-css
[GCP] GCPサービスを勝手にまとめてみた(ストレージ編)

# GCPって
https://qiita.com/risa0320/items/5f34bc9102e575705274

# サービスの分類
おおまかにはこんな感じ。（一部省略してます）
※2019年8月末時点のもの。
※α版、β版を含む。
https://cloud.google.com/products/?hl=ja よりいろいろ引用してます。

| 分類       |  サービス例    |
|:-----------------|:------------------|
| AIと機械学習   | AutoML,Vision AI,Cloud TPU... |
| API管理 | Apigee Sense,Cloud Healthcare API... |
| コンピューティング | Compute Engine,App Engine,Cloud Functions... |
| データ分析 | BigQuery,Cloud Composer,Cloud Dataflow... |
| データベース | Cloud SQL,Cloud Bigtable,Cloud Spanner... |
| デベロッパーツール | Container Registry,Cloud Build... |
| ハイブリットとマルチクラウド | Anthos,GKE On-Prem... |
| IoT | Cloud IoT Core,Edge TPU |
| 管理ツール | Stackdriver,Monitoring,Private Catalog... |
| メデイアとゲーム | Zync Render,Anvato... |
| 移行 | Cloud Data Transfer,Transfer Application... |
| ネットワーキング | Virtual Private Cloud,Cloud DNS,Cloud NAT... |
| セキュリティ | Cloud Security Scanner,Cloud IAM,Cloud HSM... |
| ストレージ | Cloud Storage,Cloud Firestore... |

# サービスをもう少し深く見てみる
## ストレージ
### Google Cloud Storage
デベロッパーや企業向けの統合型オブジェクト ストレージ
> Cloud Storage では、世界中のどこからでも、いつでもデータを保存、取得できます。データの量に制限はありません。ウェブサイト コンテンツの提供、アーカイブと障害復旧のためのデータの保存、直接ダウンロードによる大きなデータ オブジェクトのユーザーへの配布など、さまざまなシナリオで Cloud Storage を使用できます。

<機能>

* 暗号化
* オブジェクトのメタデータ
* Cloud Pub/Sub Notifications for Cloud Storage
* オブジェクト変更通知
* オブジェクトのバージョニング
* オブジェクトのライフサイクル管理
* リクエスト元による支払い
* 保持ポリシーとバケットロック
* オブジェクトのトランスコーディング
* Cloud StorageでのCloud監査ログ
* クロスオリジンリソースシェアリング

<特徴>

* 単一の統合型 API を使用してストレージをアプリに統合
* オブジェクトのライフサイクル管理を使用して 4 つのストレージ クラス間で価格とパフォーマンスを最適化
* どのストレージ クラスからでもすばやくデータにアクセス
* どのストレージ クラスからでもすばやくデータにアクセス
* データ ストレージの炭素排出量をゼロに削減

### Persistent Disk
仮想マシンのインスタンスのための信頼できる高性能ブロック ストレージ
> Google Persistent Disk は Google Cloud Platform 向けの、耐久性の高い高性能なブロック ストレージです。Google Compute Engine または Google Kubernetes Engine で実行されているインスタンスに接続できる、SSD ストレージと HDD ストレージを提供します。ストレージ容量は透過的にサイズを変更できます。また、高速バックアップや同時読み取りにも対応しています。

<特徴>

* 耐久性
* 容量
* 独立した場所での保存
* オンライン拡張

最大容量が６４TBなので、ディスク容量で困ることはほぼなさそう。

### Cloud Storage for Firebase
コンテンツを簡単に保存して提供します。
> Cloud Storage for Firebase は、Google 規模で構築された、強力かつシンプルでコスト効果の高いオブジェクト ストレージ サービスです。Cloud Storage 用の Firebase SDK では、ネットワーク品質にかかわらず、Firebase アプリでのファイルのアップロードとダウンロードに Google のセキュリティが適用されます。この SDK は、画像、音声、動画、またはその他のユーザーが生成したコンテンツを格納する場合に使用できます。サーバーでは、Google Cloud Storage を使用して同じファイルにアクセスできます。

<機能>

* 堅牢なオペレーション
* 強固なセキュリティ	
* 高いスケーラビリティ	

### Cloud Filestore
高パフォーマンスでフルマネージドのファイル ストレージ
> Cloud Filestore は、データ用のファイルシステム インターフェースと共有ファイルシステムを必要とするアプリケーション向けのマネージド ファイル ストレージ サービスです。Filestore を使用することにより、Google Compute Engine や Kubernetes Engine のインスタンスでマネージされたネットワーク接続ストレージ（NAS）をネイティブで簡単に活用できるようになります。Filestore のパフォーマンスと容量は個別に細かく調整できるため、ファイルベースのワークロードに対して、想定どおりに高速のパフォーマンスを実現できます。

<利点>

* 高速
* 一貫性
* シンプル
React dev Memo

async, await:
https://qiita.com/niusounds/items/37c1f9b021b62194e077

try, catch:

getState:

payload:

アロー関数について
https://qiita.com/may88seiji/items/4a49c7c78b55d75d693b
https://qiita.com/mejileben/items/69e5facdb60781927929

componentDidMount()
https://ja.reactjs.org/docs/react-component.html#componentdidmount

componentDidMount() は、コンポーネントがマウントされた（ツリーに挿入された）直後に呼び出されます。DOM ノードを必要とする初期化はここで行われるべきです。リモートエンドポイントからデータをロードする必要がある場合、これはネットワークリクエストを送信するのに適した場所です。

このメソッドは、購読を設定するのに適した場所です。設定した場合は、componentWillUnmount() で購読を解除することを忘れないでください。

componentDidMount() の中で、あなたはすぐに setState() を呼び出すことができます。それは余分なレンダーを引き起こしますが、ブラウザが画面を更新する前に起こります。これにより、この場合 render() が 2 回呼び出されても、ユーザーには中間状態が表示されません。このパターンはパフォーマンス上の問題を引き起こすことが多いので、慎重に使用してください。ほとんどの場合、代わりに constructor() で初期状態を state に代入できるはずです。ただし、モーダルやツールチップのような場合に、サイズや位置に応じて何かをレンダーする前に DOM ノードを測定することが必要になる場合があります。
チェックボックス一括ON/OFF

# チェックボックス一括ON/OFF

アドオンが使えない環境などで。



権限セットなどの、すべてのチェックボックスを選択するのにくたびれていませんか？

このブックマークレットは、様々なチェックボックスを一括でON/OFFに切り替えます。



- チェックボックス一括オン/オフ

```
javascript:(function(){ function toggle(box){ temp=box.onchange; box.onchange=null; box.checked=!box.checked; box.onchange=temp; } var x,k,f,j; x=document.forms; for (k=0; k<x.length; ++k) { f=x[k]; for (j=0;j<f.length;++j) if (f[j].type.toLowerCase() == "checkbox") toggle(f[j]); } })();
```
MacのローカルのMySQLがどうしても起動しない人のために


MySQLが起動しないぜ。。。

```
$ sudo mysql.server start
Starting MySQL
. ERROR! The server quit without updating PID file (/usr/local/var/mysql/your-MacBook-Air.local.pid).
```

よくある事象なので記事もたくさんありますが、どの記事を試してみても、mysqlをインスコしなおしても、あらゆる手を試しまくったが全く治らなかった・・・・

たまたまstack overflowで見つけた記事にあった方法を試したところ、解決した。

```
$ sudo /usr/local/mysql/support-files/mysql.server restart
```

参考にしたページ
[ERROR! The server quit without updating PID file on El captian >]
(https://stackoverflow.com/questions/33808938/error-the-server-quit-without-updating-pid-file-on-el-captian)
陽菜が「ねぇ、今から晴れるよ？」という瞬間を捉える

#やりたいこと
陽菜が代々木会館で「ねぇ、今から晴れるよ？」とつぶやく瞬間を捉える

#やりかた
今雨が降っていて、これから雨が止む瞬間を捉える

#気づき方
Slackに通知する。

#実現方法
Yahoo! Open Local Platformに気象情報で降水情報を発信しているので、
これを利用して雨が止む瞬間を捉える

#すると、こうなる
<img width="485" alt="hareruyo.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101834/b8301786-9b91-1b5f-733f-d92d5af14694.png">

#スクリプト
スクリプトは以下のような感じです。Gas使えるようにして、YOLPのappIDを取得すれば↓貼り付けてappidとか書き換えてgasのトリガー設定で10分ごと起動にして、お好きなSlackで作ったincomingWebHookのurl設定すりゃ動きます。たぶん。

```js:imahare.gs
function imahare(){
  var ima = 0;
  var gofungo = 0;
  var message="ねぇ、今から晴れるよ:sunny:";
  //経度、緯度＠代々木会館
  var keido = "139.7016769";
  var ido   = "35.6832461";
  //yolpのAPPID
  var appId = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
  //YOLPをコールする。位置情報と降水情報の粒度を指定
  var url = "https://map.yahooapis.jp/weather/V1/place?coordinates=" + keido + "," + ido + "&output=json&appid=" + appId + "&interval=5";
  var response = UrlFetchApp.fetch(url);
  var js = JSON.parse(response.getContentText());

  //YOLPの結果から今の降水量と5分後の降水量を取得
  ima = js.Feature[0].Property.WeatherList.Weather[0].Rainfall;  
  gofungo = js.Feature[0].Property.WeatherList.Weather[1].Rainfall;
  
  //現在降水量があって5分後予報が0だったら晴れるよっていう
  if(ima > 0){
    if(gofungo == 0){
      //SlackのincomingWebhookのurl
      var postUrl = 'https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXX/xxxxxxxxxxxxxxxxxxxxxxxxx';
      var jsonData =
      {
         "username" : "陽菜",
         "icon_url" : "https://xxxxxx",//適当な画像url
         "text" : message 
      };
      var payload = JSON.stringify(jsonData);

      var options =
      {
        "method" : "post",
        "contentType" : "application/json",
        "link_names": 1,
        "payload" : payload
      };
  
      UrlFetchApp.fetch(postUrl, options);
    }
  }
  
}
```
#動かし方参考url
YOLPのAppID取得方法
[アプリケーションIDを登録する](https://developer.yahoo.co.jp/yconnect/v1/registration.html)
incomingWebhookの作り方
[SlackのWebhook URL取得手順](https://qiita.com/vmmhypervisor/items/18c99624a84df8b31008)
[【Google Apps Script(GAS)】トリガーを設定してスクリプトを実行する](https://vba-gas.info/gas-trigger)

#参考URL
[SlackとGoogleAppsScript(GAS)を連携する手順・事例](https://tech.tabilabo.co.jp/598/)
[初心者がGASでSlack Botをつくってみた](https://tech.camph.net/slack-bot-with-gas/)
[Yahooが提供する気象情報API(YOLP) を使ってbotにお天気(降水情報)を教えてもらう~pythonでslack bot開発④~](https://qiita.com/takahirono7/items/01b1ef6bd364fffdb3c4)
[Google Apps Script試行錯誤Blog](http://www.pre-practice.net/p/blog-page_21.html)
#あとがき
やっと映画見てきました。一回記事書いたのだけど、雑すぎたのでもっかい書きました。たしょうはマシになったか？

これ作るとスマホの通知で陽菜が晴れるタイミング教えてくれるのでちょっと可愛いです。
おためしあれ！