未経験からのフルスタックエンジニア

スキルをつけよう!未経験からフリーランスエンジニアへの成長記録

Linux学習履歴(6)~シェルの賢い使い方~

以下の記事の続きです

atora1992.hatenablog.com

Linuxコマンドライン入門』が日ごとに6日間分別れているので、今回は6日目の中間地点までの内容についてです。

コマンドの備忘録的になってしまうと思いますので、悪しからず。

6日目

シェルを賢く使う

ワイルドカード応用

ワイルドカードは以下の記事で取り上げたように、「*」や「?」といった特殊文字を用いて、ファイルやディレクトリを柔軟に指定できる方法でした。

atora1992.hatenablog.com

特殊文字は、コマンドではなくシェルによって展開されます!

上記の2つに追加して新たに2つの表記法を紹介します。

  • [【文字の並び】]
  • {【文字列1】,【文字列2】,..}
[【文字の並び】]でいずれかの文字を表す

例えば、"[A-Z]"はAからZまでの文字(アルファベット大文字)の全てを表します。 ですので、以下のコマンドでは、先頭がアルファベット大文字のディレクトリ一覧を表示できます。

$ ls -ld [A-Z]*

逆に、先頭がアルファベット大文字以外を指定したければ、以下のように"^"を用います。

$ ls -ld [^A-Z]*
{【文字列1】,【文字列2】,..}で文字列を展開する

{}内に、複数の文字列をカンマで区切って記述すると、シェルはその順に文字列を展開します(ブレース展開)。

$ echo {gif,jpg}
gif jpg

※カンマの前後にスペースは入れれません

これを使えば、拡張子を指定してファイル一覧の表示などが簡単にできます。

$ ls *.{gif,jpg}

シングルクォーテーションとダブルクォーテーション

今まで、特殊文字の働きを打ち消して(クォーティング)文字として認識させるときには、シングルクォーテーションまたはダブルクォーテーションでくくってきたかと思います。

クォーテーションの中にクォーテーションを含むには、外側を違うクォーテーションでくくれば大丈夫です。

それでは、この両者は同じなのでしょうか?実は、両者には特殊文字を打ち消す力の強さに違いがあります。

強さはシングルクォーテーションの方が強いです。
シングルクォーテーション>ダブルクォーテーション

シングルクォーテーションは全ての特殊文字を打ち消します。
一方で、ダブルクォーテーションは「$」と「`」の働きは打ち消しません

ですので、以下のような違いが生まれます

$ echo "Today is `date`"  #ダブルクォーテーションでくくるので、「`」の働きは残存
→Today is 2019820日,,,

$ echo 'Today is `date`'  #シングルクォーテーションだと「`」の働きが消される
→Today is `date`

(バッククォーテーションのによるコマンド置換は以下の記事を参考にしてください)

atora1992.hatenablog.com

シングルの方が強力と覚えれば大丈夫です。

コマンド履歴の活用

コマンド履歴の一覧を表示する

$ history
$ history 【任意の数字】  #数字で指定した直近の履歴を表示

数字はヒストリ番号です。

コマンド履歴内の任意のコマンドを実行するには、ヒストリ番号を指定して実行可能です。

$ !【ヒストリ番号】


$ !!  #直前に実行されたコマンドを実行する

履歴を見るだけでなく、インクリメンタルサーチを行うことも可能です。
Ctrl + Rキー
でサーチもモードになります。

文字を入力するたびに、コマンドが検索され、目的のコマンドが見つかったらEnterを押すことで実行できます。

文字を入力して、同じ文字列で検索したい場合には、もう一度Ctrl + Rキーを押すことで可能です。

また、見つかったコマンドを編集したい場合には、Escキーを押すことで可能です。

シェル変数

シェルで使用する変数のことです。以下のコマンドで、変数に値を格納できます。

$ 【変数名】=【値】

e.g.
$ text=Hello  #textという変数にHelloを代入
$ echo $text  #$で変数から値を取り出す
→Hello

※イコールの前後にスペースは入れれません

特殊文字を値をして格納したい場合には、クォーテーションで括ります。
ただし、ある文字列ないで変数から値を取り出したい場合には、外側はダブルクォーテーションでなければなりません。というのも、シングルクォーテーションでくくると、$による値の取り出しの働きが消されてしまうからです。

変数の定義を削除する。

$ unset 【変数名】

シェル変数がどこまでなのかは、シェル側で勝手に判断してくれます。
例えば、「/」や「.」のような記号があると、その前までが変数だと判断します。

なので、変数の後に英数文字が続く場合には、変数名を{【変数名】}とくくる必要があります。

$ Main=~/Documents/Main

$ cd $Main
→~/Documents/Mainに移動
$ cp $Main/2019.txt ~
→~/Documents/Mainにある2019.textをホームディレクトリコピー

$ echo ${Main}OK
→~/Documents/MainOK

フォアグラウンド・ジョブとバックグラウンド・ジョブ

シェルはターミナル(・エミュレーター)内で実行されているコマンドをジョブとして管理します。

ジョブは以下の2つに大別されます。

  1. フォアグラウンド・ジョブ
  2. バックグラウンド・ジョブ
フォアグラウンド・ジョブ

ターミナル前面で実行されているジョブです。つまり、実行が完了するまではコマンドプロンプトは戻りません(入力できない)。

バックグラウンド・ジョブ

ターミナル背面で実行されているジョブです。つまり、同時に複数のコマンドを実行することが可能になります。

バックグラウンド・ジョブとしてコマンドを実行するには、コマンド名の後に「&」を記述します。

$ 【コマンド名】&

一度、フォアグラウンド・ジョブとして実行した後でも、バックグラウンド・ジョブにすることも可能です。

$ 【コマンド名】  #フォアグラウンド・ジョブとして実行
↓  Ctrl + Zキーでジョブを一時停止
$  #コマンドプロンプトが戻る
↓
$ bg  #バックグラウンド・ジョブに変更する

実行しているジョブの一覧を表示するにはjobsコマンドを実行します。

MacBook-Pro:~ ATORA$ xclock&
[1] 3338
MacBook-Pro:~ ATORA$ xclock&
[2] 3340
MacBook-Pro:~ ATORA$ xclock&
[3] 3341
MacBook-Pro:~ ATORA$ xclock&
[4] 3342
MacBook-Pro:~ ATORA$ jobs
[1]   Running                 xclock &
[2]   Running                 xclock &
[3]-  Running                 xclock &
[4]+  Running                 xclock &

上記の例では、xclockを4つバックグラウンド・ジョブとして実行しました。
一覧の左の数字はジョブ番号です。(各コマンド後に表示される数値はプロセスIDといいます(後述))
「+」が表示されているのがカレントジョブで、後述するfgコマンドの対象となります。
「-」が表示されているのが一つ前のカレントジョブです。

バックグラウンド・ジョブをフォアグラウンド・ジョブにするにはfgコマンドを用います。

$ fg %【ジョブ番号】

※引数なしの場合は、カレントジョブが対象となります。

バックグラウンド・ジョブを終了させるにはkillコマンドを用います。

$ kill %【ジョブ番号】
$ kill -s SIGKILL %【ジョブ番号】  #暴走状態になった(終了できない)ジョブを停止させる

ジョブというのは、実行中のシェルから見た処理の単位です。なので、ターミナルを複数立ち上げていると、どれぞれのターミナルごとにジョブ番号は1から振られていきます。

一方で、システムから見た実行中のプログラムのことはプロセスと呼びます。プロセスにはシステムで重複のないプロセスIDが振られます。

現在実行中のプロセス一覧はpsコマンドで表示できます。

$ ps

$ ps -e  #システムないの全てのプロセス一覧を表示

上記のコマンドで表示されるPIDがプロセスIDです。TTYにはジョブを実行中のターミナルの名前が表示されます。

指定したプロセスに対してシグナルを送ることも可能です。

$ kill -s 【シグナル】 【プロセスID】

シグナル例
SIGTERM:ジョブ停止命令(シグナル指定なしの場合はデフォルトでSIGTERM)
SIGKILL:SIGTERMで停止しない場合に停止させる
SIGTSTP:プログラムの一時停止(Ctrl + Zキーではこのシグナルが送られている)
SIGINT:プログラムの停止

次の記事へ

atora1992.hatenablog.com

AWS 学習履歴(6)~Route53~

AWS学習履歴の趣旨

AWSでデプロイをしたことはあるものの、AWSの理解に足りない部分があるのが悔しいと思い、UdemyのAWS講座で勉強を開始しました。

以下の記事の続きです。

atora1992.hatenablog.com

学習内容を全て残すことは量が莫大になるので無理ですが、『重要かな?と思った部分を記録として残そう!』というのが趣旨です。

更新頻度は不定期ですが、地道に続けていこうかと思います。

応援よろしくお願いします。

Route53

ルーティング設定サービス。
DNS(Domain Name Service)を提供するAWSのサービスです。

主要機能は以下の3つです。

  1. ドメイン登録
  2. DNSルーティング
  3. ヘルスチェック

ヘルシチェックは1つ1つのIPアドレスでのチェックが可能です。ヘルスチェックを用いたルーティングも可能です。

DNS

DNSはURLをIPアドレスに変換する仕組みです(名前解決)。

DNSサーバーには以下の2つがあります。

種類 説明
権威DNSサーバー 名前解決機能あり
キャッシュDNSサーバー 企業サーバーに一時的にDNS情報を保持する

Route53は「権威DNSサーバー」です。

基本の設定順序

  1. Route53にドメインを設定
  2. ドメイン名と同じホストゾーンを自動生成
  3. ホストゾーンにルーティング方法となるDNSレコードを作成
  4. トラフィックルーティングを設定

ホストゾーンとは、ドメインとそのドメイントラフィックルーティング方法についての情報を保持するコンテナです。

ドメインが"○○○.com"ならば、サブドメインは"△△△.○○○.com"といったように、ドメインの前に文字列を挿入して、1つのドメインを複数に分割する方法です。

次の記事へ

atora1992.hatenablog.com

AWS 学習履歴(5)~Reliability・ELB・Auto-Scaling・RDS~

AWS学習履歴の趣旨

AWSでデプロイをしたことはあるものの、AWSの理解に足りない部分があるのが悔しいと思い、UdemyのAWS講座で勉強を開始しました。

以下の記事の続きです。

atora1992.hatenablog.com

学習内容を全て残すことは量が莫大になるので無理ですが、『重要かな?と思った部分を記録として残そう!』というのが趣旨です。

更新頻度は不定期ですが、地道に続けていこうかと思います。

応援よろしくお願いします。

Reliability(信頼性)の確保

Well Architected Frameworkのうちの一つです。

atora1992.hatenablog.com

重要な点は2点です。

  • 耐障害性の向上
  • 高可用性の確保

耐障害性の向上

障害による中断・停止とそこからの復旧による影響を軽減させることです。

  • 別リージョンや別AZにバックアップを取得管理
  • 別リージョンや別AZにスタンバイ構成をとり、即座にフェイルオーバー(あるシステムに異常が発生した時、自動的に冗長なシステムに切り替えること)できるようにする
  • BCP(事業継続計画)を整備し、バックアップからの復元やフェイルオーバーなどの手順を検証する

これら3点が耐障害性の向上の基本になる。

高可用性の確保

高可用性とは、なるべくダウンタイムをゼロにすること。

  • AWS提供の高可用性なサービスの利用(S3は9 elevenと言われ、耐久性が99.999999999%ある)
  • 高可用なアーキテクチャを設計する(EC2が代表)

この2点が基本になる。

関連するベストプラクティスは「単一障害点の排除」であり、このためにELB(Elastic Load Balancing)が用いられる。

EC2だけでなくDBも同様に設計する必要があり、例えばマスターDBのコピー(スレーブ)にレプリケーションを常にとり、マスターがダウンしても自動でフェイルオーバーするように設計するなど。

EC2に対しては、ElasticIPをインスタンス障害時に同じパブリックIPをもつインスタンスにフローティング(別の代替サーバーにIPを移す)などして対策もできる。

ELB

EC2インスタンスの処理を分散させるものです。

ヘルスチェック(インスタンスの正常・異常をチェック)して、異常なインスタンスを認識し、そちらにトラフィックを回さないなどもできます。

また、ELB配下のインスタンスの負荷に応じてインスタンスの負荷分散(トラフィック量を分散させる)ことも可能です。

ELBを用いて、ベストプラクティスの1つスケーラビリティ(需要変化に対応させる)を確保します。

Auto-Scaling

スケーラビリティの確保に重要になるサービスです。

サーバーへの需要変化に応じて、インスタンスをスケーリングする機能です。

スケーリングには以下の2つがありますが、Auto-Scalingは「水平スケーリング」です。

  • 垂直スケーリング:メモリやCPUの追加・増強(スケールアップ)/削除・低性能化(スケールダウン)
  • 水平スケーリング:処理する機器/サーバー台数の増加(スケールアウト)/低減(スケールイン)

例えば、ELBで需要の負荷分散はできますが、分散させても処理できるトラフィック量を超えてしまう場合に、新しいEC2を立ち上げることが可能です。
逆に、需要が減った場合に不必要なインスタンスを削除することも可能です。

RDS

様々なデータベースソフトウェア(MySQL, ORACLE, ..etc)に対応したリレーショナルデータベース。

AWSでのデータベース構築は以下の2つのやり方がある。

  1. EC2に自らインストールする
  2. 専用DBサービス(RDS等)を利用する

「1. EC2に自らインストールする」場合は、自由なDB構成や機能を利用できますが、構築・運用の手間が多くなります。

「2. 専用DBサービス(RDS等)を利用する」場合は、構築・運用はAWSが大部分をになってくれますが、AWSの機能範囲内でしかソフトウェアを使うことができません。

RDSでは、高可用性の確保で例にだしたマスター・スレーブ構成の構築が簡単です(同期レプリケーション・自動フェイルオーバー)。
さらに、非同期レプリケーションでリードレプリカ(参照専用:データ読み取り処理スピードを向上できる)を設置できます。
また、Snapshotによる耐障害性の確保もできますし、マスターを複数構成にしてRDSの書き込み処理もスケーリング可能です(データベースシャーディング)。例えば、ID:0~100はこっちのRDS、ID:101~200は違うRDSなどと、ユーザーIDに応じてアクセス先を変えることも可能です。

次の記事へ

atora1992.hatenablog.com

AWS 学習履歴(4)~AWSアーキテクチャ設計・ベストプラクティス~

AWS学習履歴の趣旨

AWSでデプロイをしたことはあるものの、AWSの理解に足りない部分があるのが悔しいと思い、UdemyのAWS講座で勉強を開始しました。

以下の記事の続きです。

atora1992.hatenablog.com

学習内容を全て残すことは量が莫大になるので無理ですが、『重要かな?と思った部分を記録として残そう!』というのが趣旨です。

更新頻度は不定期ですが、地道に続けていこうかと思います。

応援よろしくお願いします。

AWSアーキテクチャ設計の基礎

AZの選択

1つのリージョンについて、2つのAZが基本。
マルチAZにサーバーやDBの冗長構成を確立し、高い可用性(システムがどれだけ継続して稼働できるかという能力)を実現する。
また、S3にDBのバックアップをとっていく。

VPC

atora1992.hatenablog.com

2つ以上のVPCが基本(小規模なシステムでは1つの方がいい場合もある)。

どのような方式でVPCを設置するのかは以下の2方式がある。

  • マルチVPC方式:2つのAZにまたいで、複数VPCで複数システムに分割する
  • マルチアカウント方式:アカウントごとにVPCをもつ。例えば、VPCで部署単位に分割するなど

サブネットの分割

パブリックサブネットとプライベートサブネットに分割して、インターネットアクセス範囲を定義する。
1つのAZに対して1対のサブネットが基本。

VPC間の接続

VPC Peeringを用いてVPC間を接続する。
VPCが多い時には、どことどこのVPCが繋がる必要があるのかを考えていく。

Well Architected Framework

AWSが提唱している設計原則。以下の5項目から成り立つ。

項目 説明
Reliability:信頼性 障害による中断・停止とそこからの復旧による影響を軽減させる
Performance Efficiency:パフォーマンス効率 システム要件を満たしつつ、リソースを活用してインフラを効率化する
Security:セキュリティ AWS内のデータ・システム・アセットの保護とモニタリングによりセキュリティを高める
Cost Optimization:コスト最適化 不必要なリソースの削減や最適な料金選択によりコストを削減する
Operational Excellence:運用上の優秀性 計画変更・予期せぬイベント発生時、自動化された運用実務・文書化されテストされレビューされた手順があること

全てに共通して言えることは、日々アップデートされるAWSリソースを用いて、インフラの設計もアップデート・改善させていくということかと思う。

また、アップデートして最適化させていく為にも、今の現状を把握することが重要になってくる。

上記の5つを念頭において、インフラを設計していくことが大事!

AWSベストプラクティス

AWSが提唱するインフラ設計におけるベストプラクティスは11ある。(Well Architected Frameworkを実現するための具体的な方法といったところだろうか)

  1. スケーラビリティの確保
  2. 環境の自動化
  3. 使い捨てリソースの使用
  4. コンポーネント疎結合
  5. サーバーでなくサービス(サーバレス)
  6. 最適なDB選択
  7. 増大するデータ量対応
  8. 単一障害点の排除
  9. コスト最適化
  10. キャッシュの利用
  11. セキュリティの確保

スケーラビリティの確保

需要変化に対応できるようにする。

e.g.
EC2 Auto Recovery, EC2 Auto Scaling, Cloud Watch, RDS, Dynamo DB

環境の自動化

主要プロセスの自動化により、システムの安定性・整合性・組織の効率性を改善させる。

e.g.
Cloud Formation, Codeシリーズ(構築自動化ツール), ECS, Elastic Beanstalk, OpsWorks, Cloud Watch

使い捨てリソースの利用

サーバーなどのコンポーネントを一時的リソースとして利用・設計する。

e.g.
EC2(すぐに作成できて、削除できる), Auto Scaling

コンポーネント疎結合

コンポーネント間の相互依存を減らし、1つのコンポーネントの障害・変更による全体への影響を軽減する。

e.g.
ELB, SNS, SQS

サーバーでなくサービス(サーバレス)

マネージド型サービスとサーバレスアーキテクチャにより、効率的な設計・運用を実現する。

e.g.
Lambda, SNS, SQS, ELB, SES, DynamoDB, Amazon API Gateway, Amazon Cognito

最適なDB選択

ワークロードに応じた最適なDBを利用する。

e.g.
RedShift, RDS, Dynamo DB, Aurora, Elastic Search

増大するデータ量対応

絶えず増加するデータの保持を効率的に実施する。(ビッグデータ/ IoTなど)

e.g.
S3, Kinesis, Glacier

単一障害点の排除

単一障害点とは、「その箇所が動かなくなると、システム全体に障害を引き起こしてしまうような点」のことをいう。
AWSサービスの多くは高可用性が担保されているが、EC2・RDSなどユーザーが設計する必要のある部分についてはユーザー側で高可用性を実現するよう設計する必要がある。

コスト最適化

リソースサイズの最適化・最適な料金プランの選択などにより、コストを最適化する。

キャッシュの利用

繰り返し取り出すようなデータ・コンテンツはキャッシュを利用する。

e.g.
Cloud Front, ElastiCache

セキュリティの確保

全て(リソース外も含めて)にセキュリティを実装する。


細かくプラクティスごとに例をつけましたが、それぞれの内容(全ては難しいですが)については今後触れていきたいと思いますので、少々お待ちください。

インフラの設計は考えることが多くて大変ですね。。
設計するにもそれぞれで用いるリソースを理解する必要がありますし。。

少しづつでも理解を進めて、インフラの設計ができるようになりたいです!

次の記事へ

atora1992.hatenablog.com

【Web入門】Cookieって何?~セッションとの違いも~

こんにちは、ATORAです!(@ATORA1992)

今回は、Cookie(クッキー)についてまとめたいと思います。

Cookieという言葉は、パソコンを触っていれば一度は耳にしたことがあるかと思います。「Cookieを有効化・無効化しますか?」など聞かれたこともあった気がします。それでは、Cookieとはそもそもなんなのでしょうか?詳細までわからなくとも、何をするものなのかという知識を身につけ、一緒にエンジニアへの一歩を踏み出しましょう!

目次

  • Cookieとは何?
  • Cookieと似た仕組みでSession(セッション)があるけど違いは何?

という2点についてお話したいと思います。

Cookieとは何?

その前に、HTTPとは何か?

HTTP(Hyper Text Transfer Protocol)という通信プロトコルです。

通信プロトコルとは、情報の伝達とその意味づけをどうするかという取り決めのことです。この取り決めがあることで、インターネットで色々なホームページを表示することができています。

HTTP通信でなんでホームページなどが見れるの?

ざっくり、ホームページなどのアプリケーション(Webアプリケーション)は、Webブラウザ(クライアント:ユーザー側)Webサーバー間でHTTP通信を行うことで成り立っています。

HTTP通信でのやりとり概略図

まずは、クライアントからサーバー側にリクエストを送ります(HTTPリクエス)。すると、そのリクエストに基づいてサーバーからクライアントにレスポンスが返ってきます(HTTPレスポンス)。このやりとりにはHTTP通信が使われています。

例えば、リクエストで「どこどこのページが見たい」と送ったとします。すると、そのページを表示するのに必要なファイル(HTMLなど)がサーバー側からレスポンスとして返ってきます。それによって、ホームページを見ることができるようになるわけですね。

このように、一回のリクエストを送れば用が済んでしまうのがHTTPでの利点です。ただし、前回のリクエスト結果をサーバーは覚えていません。このようなプロトコルステートレス・プロトコル(Stateless Protocol)と呼びます。逆に、状態を持つプロトコル(例えばFTP)もあり、それはステートフル・プロトコル(Stateful Protocol)と呼ばれます。

例えば、行きつけのお店があったとします。「マスター、いつもの!」というだけでOKなのがステートフル・プロトコル(履歴が登録されている)で、毎回説明しなければならないのがステートレス・プロトコル(履歴がない)です。

このステートレスなHTTP上で状態を表現する方法がCookieです。

Cookieによる状態の保持

Cookie概略図

まずは、クライアントからサーバーへリクエストを送ります。その後、サーバー側からレスポンスが返ってくるわけですが、HTTPレスポンスにCookieという情報(名前=値という組み合わせで表されている)を乗せて返します。

Cookieを受け取ったクライアントは、次回同じサーバーにアクセスする際に、受け取ったCookieをそのままHTTPリクエストに乗せて送ります。このCookieをサーバーが調べることで、クライアントを識別できる(状態を表現できる)わけです。

「このままだと、違うサーバーにもCookieが送られてしまうんじゃない?」と思うかもしれませんが大丈夫です。Cookieを受け取ったサーバーとは異なるサーバーに対してはCookieを送りません。

Cookieはどこに保存されるの?

Cookieの概要はわかりましたが、Cookieはそもそもどこに保持・保存されるのでしょうか?

結論は、クライアントのPC上です。Google Chromeだったら、環境設定>詳細設定>プライバシーとセキュリティ>サイトの設定>Cookieで見ることができます。

ここで考えてみてください。簡単にCookieの内容は見れるし、HTTPリクエストの中身もChromeなら検証ツールなどを使えば簡単に見れます。簡単に見れる所に、ユーザーのクレジットカード情報やパスワード情報があったらどうでしょうか?危険ですよね?

そこで、より安全に多くの情報を保持するための仕組みがSession(セッション)です。

Sessionとは何?

Sessionは一連の処理

SessionはWebアプリケーションにおける一連の処理を指します。例えば、ログインして→商品をカートに入れ→注文内容を確認して→購入し→ログアウトするなどの処理の流れです。

この一連の処理を実現するには複数回HTTPリクエストが必要ですね?この複数回のリクエストの最中には、ログインしているユーザーの情報を保持したり、カート内の商品情報を保持しなければなりません。つまり、これらの処理を実行中に状態を保持する必要があります。その保持の仕方は例えば、セッション管理の表(どこまで処理が行われているのか)があるのを想像してもらえれば大丈夫です。

では、この表をどのように管理しましょう?Cookieで渡してしまっては情報漏洩などの危険があります。そこで、この表はクライアントには渡さずサーバー側で管理します。

では、どうやってクライアントを識別するのか?実は、ここでCookieを使います。

「それでは、何も変わらないんじゃない?」と思われるかもしれませんが、Cookieに入れる情報はセッションIDです。

セッションID

セッションIDはクライアントを識別する識別子です。例えるなら、銀行などでの受付番号みたいなものです。つまり、クライアントとセッションIDが紐づいています。さらに、このセッションIDとセッション管理表が紐づくことで、セッションIDさえあればサーバー側はクライアントを識別し、そのクライアントの状態を参照することができます。(もちろん、クライアントそれぞれに違うセッションIDが振られます)

Sessionの概略図

クライアントからリクエストが送られ、そのクライアントと紐づいたセッションID・セッション状態の情報をサーバーが作成します。レスポンスではCookieにセッションIDのみを乗せて返します。次回以降、クライアントがサーバーにリクエストする際には、このCookieをリクエストに乗せて送ります。サーバーはCookieで送られてきたセッションIDを元にクライアントを識別し、そのクライアントのセッション状態の情報を参照します。

このように、セッションを用いることで安全に多くの情報を保持することができるわけですね!

まとめ

  • HTTP通信はステートレスなプロトコル
  • ステートレス・プロトコルで状態を表現する方法がCookie
  • ただし、Cookieは情報漏洩の危険がある
  • 安全に多くの情報を保持する仕組みがセッション
  • セッションIDをCookieでやりとりすることで安全性が高まる

特に違いとして大きいのは、Cookieでは情報がクライアントのPC上に保存されるが、Sessionの情報(セッション管理表)はサーバー上に保存されるということです。

ここさえつかめればいいかなと思います。

一歩でも前に進む手助けになれば嬉しいです。
また、お会いしましょう。
ATORAでした!!

Linux学習履歴(5)~ユーザー管理・権限管理~

以下の記事の続きです

atora1992.hatenablog.com

Linuxコマンドライン入門』が日ごとに6日間分別れているので、今回は5日目の内容についてです。

コマンドの備忘録的になってしまうと思いますので、悪しからず。

5日目

ユーザー管理

Who am I?

LinuxなどのUNIX系OSはマルチユーザーシステムです。つまり、同時に複数のユーザーが使用することを前提としたOSです。よって、ユーザー管理を適切に行う必要があります。

ユーザーには大きく分けて以下の2つがあります。

  • スーパーユーザー:全ての権限をもつ。ルートユーザーともいう
  • 一般ユーザー:スーパーユーザー以外のユーザー

そして、ユーザー一人単位だけでなく、グループ単位でも権限が設定できます。

自分のユーザー名、所属するグループ名を確認するには以下のコマンドを実行します。

$ whoami  #自分のユーザー名を確認
$ groups  #所属するグループ名を確認

所属するグループ名を確認した時に先頭に表示されるグループは、プライマリグループと呼ばれます。最近のLInuxでは、初期状態でプライマリグループはユーザー名と同じ名前のグループ(プライベートグループ)らしいです(自分は確認時点で違いました)。プライベートグループはグループ名のユーザーしか属していないグループです。

上記のコマンド実行結果は英数字で表示されたかと思いますが、システム内部ではそれぞれユーザーID、グループIDで管理されます。このIDを確認するコマンドが下記のコマンドです。

$ id

#結果の具体例
uid = 500(ATORA) gid = 500(ATORA) groups = 500(ATORA), ...

コマンド実行結果は左から順に、「ユーザーID、プライマリグループのID、全てのグループのID」となっています。

別のユーザーになる

ターミナル・エミュレータ内で一時的に別のユーザーになることが可能です

$ su [ユーザー名]  #Switch Userの略

$ exit  #元のユーザーに戻る

ユーザー名はあらかじめ登録されている必要があります。また、そのユーザーのパスワードを知っている必要があります。

ただし、上記のコマンドの場合、ユーザー名(ユーザーID)は変わりますが、ホームディレクトリなどの環境は変わりません。環境も含めて移行するにはハイフンを追加します。

$ su - [ユーザー名]

上記コマンドでユーザー名を入力しなければスーパーユーザーになれます。ただし、スーパーユーザーのパスワード入力が必要です。(macでは初期でスーパーユーザーは設定されていないので https://support.apple.com/ja-jp/HT204012の内容を確認して設定してみてください)

この方法では、一時的であってもスーパーユーザーになってしまい、元のユーザーに戻ることを忘れたままにすると危険です。そこで、スーパーユーザーの権限が必要なコマンドをより安全に実行する方法として、以下のコマンドがあります。

$ sudo [コマンド名]

このコマンドでもパスワードを聞かれますが、そこで入力するのは自分のパスワードです。スーパーユーザーのパスワードではないことに注意してください。

ファイル・ディレクトリの権限

全てのファイル・ディレクトリにはその所有者と所有グループが決められています。また、ファイル・ディレクトリのアクセス権は「所有者」「所有グループ」「その他のユーザ」という単位で設定できます。

コマンドで権限を確認するには以下の方法が簡単です。

$ ls -l

実行結果の例
drwxrwxr-x 10 ATORA staff 3000 8 8 10:00 Documents 

初めの英字の羅列(先頭の1文字はファイルの形式を表しています。この場合はディレクトリです)がアクセス権を表し、"ATORA staff"が所有者・所有グループを表しています。

まず簡単な方から説明すると、"ATORA staff"の前者が「所有者」、後者が「所有グループです」

アクセス権は9文字の英字で表されています。先頭から3文字ずつがセットで、順に「所有者」「所有グループ」「その他のユーザー」のアクセス権を表しています。つまり、所有者のアクセス権=rwx、所有グループのアクセス権=rwx、その他のユーザーのアクセス権=r-xとなります。それぞれの英字には以下の意味があります。

要素 説明
r 読み出し
w 書き換え
x 実行
- 不許可

よって、上記の例では「所有者」「所有グループ」は全て許可されており、「その他のユーザー」だけ書き換えができないということになります。

ファイルのアクセス権

ファイルの「実行」とは、そのファイルをコマンドとして実行できることを意味しています。なので、ls自体のアクセス権を見ると、全てに対して実行が許可されています。

$ ls -l /bin/ls
-rwxr-xr-x ...

アクセス権を変更するには記号または数値で指定する方法があります(まずは記号で指定する方法)。

$ chmod [利用者を表す記号] [オペレーター] [アクセス権] [ファイルのパス]  #チェンジモード

利用者を表す記号

記号 説明
u 所有者
g 所有グループ
o その他のユーザー
a 全て

オペレーター

記号 説明
+ 許可を与える
- 許可を取り消す
= 元の設定をクリアして、新たに設定する

具体例

$ chmod a+w [ファイルのパス]  #全てのユーザーに書き換えを許可する
$ chmod ug-rw [ファイルのパス]  #所有者と所有グループの読み出しと書き換えを不許可にする
$ chmod a=r [ファイルのパス]  #全てのユーザーに読み出しのみを許可する 

※所属するグループに許可されていても、所有者に許可されていない場合は、所有者はアクセス権がないことになります
※アクセス権を変更できるのは、所有者かスーパーユーザーの権限が必要です。

ファイルの書き換えを不許可にした場合でも、削除・移動ができてしまいます。ファイルの削除・移動をできなくするには、ディレクトリの権限を変える必要があります。

ディレクトリのアクセス権

ディレクトリのアクセス権は、ファイルのアクセス権と意味合いがちょっと違います。

要素 説明
r(読み出し) ディレクトリ内のファイル一覧を表示できる
w(書き換え) ディレクトリ内にファイルを作成・名前の変更・移動が可能
x(実行) ディレクトリの下に進める
読み出し不許可

読み出しが不許可の場合でも、そのディレクトリにファイルを作成できますし、ディレクトリに進むこともできます。

書き換え不許可

書き換えが不許可というのは、ディレクトリに格納されているファイルの一覧を変更できなくするということです。よって、書き換え不許可のディレクトリでファイルを作成することはもちろん、ディレクトリに属しているファイルの削除や移動もできません。

ディレクトリもディレクトリファイルであることを考えれば、ファイルの変更が効かない=ディレクトリのファイル構成(直下にあるもの)をいじれないということがわかるかと思います。

ただし、ディレクトリに属するファイルを他のディレクトリにコピーしたり、内容を表示することは可能です。

実行不許可

実行不許可の場合、cdでそのディレクトリ、さらにはサブディレクトリにも移動できません。また、findによる検索もできなくなります。

数値でのアクセス権設定

chmod [3桁の8進数] [ファイルのパス]
8進数への変換
  1. 許可されていれば「1」、不許可なら「0」とします
  2. 記号でのアクセス権の考えを元に、rwxのぞれぞれに対し許可・不許可を考え、1か0に置き換えます(e.g. rw- = 110:実行のみ不許可)
  3. 置き換えた3桁の数値が2進数です
  4. 所有者、所有グループ、その他のユーザー全てで2進数に置き換えます
  5. 2進数を8進数します(最小000=0、最大111=7)
  6. 8進数を所有者、所有グループ、その他のユーザーの順に並べます

例えばrwxrw-r-xの場合、2進数だと111110101、8進数に3桁ずつ変換すると765となります。

以下の2つのコマンドは同じ結果となります

$ chmod a=rw [ファイルのパス]
$ chmod 666 [ファイルのパス]
ディレクトリ以下をまとめてアクセス権を設定

ディレクトリ以下のアクセス権をまとめて変更するにはRオプションをつけて実行します。

$ chmod -R [利用者を表す記号] [オペレーター] [アクセス権] [ファイルのパス]
$ chmod -R [3桁の8進数] [ファイルのパス]

所有者・所有グループの変更

所有者の変更

$ chown [ユーザー名] [ファイルのパス]
※スーパーユーザーの権限が必要です

所有グループの変更

$ chgrp [グループ名] [ファイルのパス]
※ファイルの所有者かつ変更するグループに属しているか、スーパーユーザーの権限が必要です

所有者・所有グループをまとめて変更するには

$ chown [ユーザー名] : [グループ名] [ファイルのパス]

上記コマンドどちらもRオプションをつけることで、ディレクトリ以下の所有者・所有グループをまとめて変更できます。

ファイル・システム情報

ファイル情報

ファイルサイズを調べる

$ ls -l  #サイズがバイト単位で確認できる
$ ls -lh  #サイズにK(キロバイト)やM(メガバイト)といった単位がつく
$ ls -s  #サイズのみを左に表示する
※lsコマンドの出力はデフォルトでアルファベット順

$ ls -shS  #サイズの大きい順に表示
$ ls -shSr  #サイズの小さい順に表示

上記のコマンドでは、ディレクトリの合計サイズまではわかりません。そこで以下のコマンドが使えます。

$ du -k [ファイルのパス]  #キロバイト単位で表示
$ du -h [ファイルのパス]  #単位を表示

$ du -h [ディレクトリのパス]  #ディレクトリ以下のディレクトリそれぞれの合計サイズを表示
$ du -sh [ディレクトリのパス]  #指定したディレクトリ以下の合計サイズを表示
$ du -ah [ディレクトリのパス]  #ディレクトリだけでなく、ファイルのサイズも表示

上記のコマンドと他のコマンドを組み合わせることも可能です。

$ du -k ~ | sort -nr | head  #ホームディレクトリ以下の各ディレクトリサイズを調べて(du)、その数値で大きい順に並び替え(sort)、上位10個を表示する(head)
※sortコマンドで数値で並び替えをしたいので、duにhオプションを指定して単位をつけてはいけません

パーティションごとの使用状況を表示するには以下のコマンドを使用します。

$ df -h  #Size=容量、Used=使用している領域、Avail=空き領域、Use%=パーセンテージ

ファイルの種類を調べる。

$ file [ファイルのパス]

システム情報

$ uname  #OSの名前を表示
$ uname -r  #OSのバージョンを表示
$ uname -p  #プロセッサの種類を表示
$ uname -a  #全ての情報を表示

$ uptime  #稼働時間を表示(左から順に、現在時刻・システムが起動してからの経過時間・現在ログインしているユーザー数・最近1分、5分、15分間のシステムの平均負荷)

$ top  #macのメモリ使用量を1秒更新で表示(qで終了)

次の記事へ

atora1992.hatenablog.com

JS(jQuery)でフォームを送信・バリデーション(w/ Rails)

やりたいこと

フォーム内容をコントローラに送信する前に、「データの成形」「バリデーション」をしたい。

やれるようになること

  • ビューをリロードすることなく、エラーメッセージを表示できる
  • フォームのデータを成形して、フォームの入力内容以外の情報をもコントローラに渡せる

概要

  1. フォームの送信ボタン(id="submit_btn"とします)が押される
  2. JSのイベントが発火
  3. フォーム送信を止める
  4. JSでデータを操作
  5. JSで本送信

コード概要

概要でできることは

  1. フォームの送信の止め方
  2. コントローラに渡す情報の追加方法
  3. バリデーション
  4. エラーメッセージの表示

フォームはニックネーム入力欄のみと仮定します

= form_for @user,  html: {id: 'submit__btn'} do |f|
    = f.text_field :nickname, class: "nickname_input"
    #error  #エラーメッセージ表示場所
#add_info  #JSでのデータ追加場所
//送信ボタンがクリックされた時にイベントが発火する
   $('#submit_btn').on('click', function(e){
      e.preventDefault();  //フォーム送信を止める 

      var nicknameLength =  $('.nickname_input').val().length  //ニックネームの文字数を取得
      //取得した文字数を値にもつ、見えないinputタグを生成する
      $("#add_info").append(
        $('<input type="hidden" name="nickname_length">').val(nicknameLength)
      ); 
      
      //ニックネームが入力されているかをバリデーション
      if (nicknameLength >= 1 ) {
        $('#submit_btn').submit();  //入力されている場合本送信
      } else {
        //入力されていない場合、エラーメッセージを作成
        var errorHtml = `<ul id= 'upload-error'>
                          <li>ニックネームを入力してください</li>
                         </ul>`
        $('#upload-error').remove();  //すでに表示しているエラーメッセージがある場合削除
        $('#error').append(errorHtml);  //エラーメッセージをビューに追加
        $('html,body').scrollTop(0);  //ページのトップへスクロール
      }
    });
1. フォームの送信の止め方

まずは、送信ボタンがクリックされた時にイベントを発火させます。
続いて、以下の記述でフォームの送信をストップします。

e.preventDefault(); 
2. コントローラに渡す情報の追加方法

フォームの情報を元に、新たなデータをinputタグを用いて追加します。
typeを"hidden"にすることでビューには表示されませんが、コントローラではparams[:nickname_length]としてこのタグの情報を取得できます。

      $("#add_info").append(
        $('<input type="hidden" name="nickname_length">').val(nicknameLength)
      ); 
3. バリデーション

フォームの情報を元に、入力されているかを確認します。
入力されている場合は、本送信を行います。

     if (nicknameLength >= 1 ) {
        $('#submit_btn').submit();   //本送信
      } else {
4. エラーメッセージの表示

バリデーションに引っかかった場合、エラーメッセージを作成し、ビューに追加します。この場合は、本送信は行いません。

        var errorHtml = `<ul id= 'upload-error'>
                          <li>ニックネームを入力してください</li>
                         </ul>`
        $('#upload-error').remove();  //すでに表示しているエラーメッセージがある場合削除
        $('#error').append(errorHtml);  //エラーメッセージをビューに追加
        $('html,body').scrollTop(0);  //ページのトップへスクロール

まとめ

JSでのデータ成形・バリデーションができれば、ビュー上でユーザーが操作した情報を元に新たなデータを作成・送信できたり、バリデーションもページリロードなしでできるので、入力内容・選択内容がリセットされずUXも向上するかと思います。

今回は、本当に簡単な例で紹介させていただきましたが、いくらでも応用可能かと思いますので、色々試してみてくださいね。