jwtについて軽く調べた
仕事でjwt使う〜?って話になったので雰囲気しかしらなかったので調べてみた
jwtとは
<header>.<payload>.<sign>
で構成されている- 各要素が
.(dot)
で区切られている
- 各要素が
- header
{"typ": "JWT", "alg": "HS256"}
- typはJWTの文字列でjwtで有ることを表していて
- algは署名アルゴリズム
- HS256はHMAC SHA-256を表している
- 関連仕様
よくある作り方
- headerをbase64url encode
- payloadをbase64url encode
.
で結合- 結合した文字列でhashを取る
- ハッシュ値を文字列の末尾に結合する
気になったこと
- header, payloadはbase64エンコードをしているだけだが秘密鍵がもれない限りは同じ署名を作成できない > 改竄検出
- 鍵のローテション
- 一定時間で変更しないといけない
- awsだとkms(Key Management Service)とか使うのか?
- とりあえず手作業だと無理
- cookieの不安
alg:none
脆弱性- jwtは
alg:none
にすると署名検証を行わないことが可能 - ライブラリとかを使用する場合は注意必要
- jwtは
- tokenの流出時について
- tokenを直接無効はできない
- 該当アカウントを一時的に無効化(tokenのexpまで)
- 該当tokenのRefresh tokenを失効テーブルのようなものに登録
- 期限切れ後アカウントを有効にし再度ログインさせる
- tokenを直接無効はできない
- 鍵の更新時
- 鍵を更新する際に完全に置き換えると全員ログアウトさせる必要がある
- 以前の鍵で署名されたものは検証を通過できない
- 両方の鍵を運用する必要があり
KeyId
のようなものが必要 - 古い鍵で署名を検証し、送り返す際に新しい鍵で署名をする必要がある
- 鍵を更新する際に完全に置き換えると全員ログアウトさせる必要がある
まとめ
jwt楽でいいぞーと言われたけど、鍵の運用・更新周りが脳死で使うにはちょっとむずかしいなと感じた
どこまでセキュリティ意識するのか問題なのかも?
今からReactを始める人に向けた型の話
周りでこれからReact始める人とかが増えてきて、以外と知られてないんだな〜ってことがあったのでReactに型をつけるというかTypeScript(以下ts), Flowと prop-typesの関係について書く
tl;dr
- prop-typeはやめとけ
- tsはいいぞ
prop-typesとは
昔はReactのcoreに入ってけどFlowが出てきたりでcoreから切り離して後方互換性のためにいパッケージとして切り出されたもの
Prop-TypesでもコンポーネントがどのようなPropsを受け取るのかを表現できなくはないが、Flow, tsに比べると表現力が乏しいので、これから作るもので使うのはおすすめしない
表現力が乏しいっていうのはPropTypesだとx
は{a: number, b: number}
のオブジェクト、y
はただのnumberだとした時に以下のような定義になる
MyComponent.propTypes = { x: PropTypes.Object.isRequired, y: PropTypes.Number.isRequired }
これがFlowやtsだと以下のように書けるのでx
がa
とb
というプロパティを持っていることがわかる(例はtypescript)
type Props = { x: {a: number, b: number} y: number } function MyComponent(props: Props) {}
Flow
Flowはfacebook製のOSSでOCamlで実装されている
最近のは使ってないのでよくわかってないが、前に使った経験的にはtsより推論が賢かったイメージがある
Reactをよくある構成で使う時はflow-typedで型が見つかるが、ちょっと珍しいライブラリとかだと型定義自作する所から始まるイメージ 記事書きながら見てみたらめっちゃ増えてたけどtsに比べるとちょっと辛そう
TypeScript
令和の時代はライブラリもtsで書きますよねって発表されてるくらい来てるts
使い捨ての処理書く時とか以外は3, 4年前から仕事でもずっとts書いてる
Flowでいうflow-typed的な有志による型定義が集まってるDefinitelyTypedがとにかく色々あるので、最近はライブラリがtypescript用の型定義を用意してくれてるものも増えたけど、無い時はDefinitelyTyped探せばよっぽど変なライブラリを持ってこない限りは大体ここにあるイメージがある
型があると補完だったり、静的チェックだったりとにかく良いし、型推論が優秀なので関数のインターフェースをちゃんと書けば特に型を書かなくてもいい感じに推論してくれるので基本的にメリットを感じることはあってもデメリットを感じることはないです
まとめ
そもそもFlow, tsとprop-typesを同じレベルで言っていいのか?とか思ったけど今後説明しなくて良いように書いた
個人的にはtsをサポートしてるライブラリ等も増えてきてるし、関西だとkansai.tsとかあったりするので特段理由が無ければts使ってればいいのでは無いかと思う kansaits.connpass.com
最後に型がいい感じに書けた時とっても気持ちいいのでtsはいいぞ〜
Go Modules時代のimport
最近ちょこちょこGolangを勉強していて、1.13になってデフォルトONになるgo modulesを使った時にimportをどうやるのかわからなくて困ったのでメモ
tl;dr
go.mod
のmodule
項目とwikiを見て
gopath mode
go modulesじゃない時はGOPATHがあったのでimport
の時は$GOPATH/src
が見えないけどついてるイメージでプロジェクトがgithub.com/yuzu441/nogi
なのであれば
import "github.com/yuzu441/nogi/package"
と書けば指定したパッケージがimportできる
module-aware mode
go modulesを使う設定にするとGOPATHがないのでパッケージ名の指定をどうするのかがわからなかったが、githubのwikiを見ていると答えが書いてあった
go modules環境ではgo.mod
というファイルがあって
これを生成するのにgo mod init
というコマンドを使うんだけど、これの後ろにgithub.com/yuzu441/nogi
のように指定してやる
go mod init github.com/yuzu441/nogi
するとgo.mod
ファイルの先頭にmodule github.com/yuzu441/nogi
のように記述されgopathモードの時と同じようにパッケージを参照できる
なので以下のように実行すると
go mod init yuzu441/nogi
yuzu441/nogi
でアクセスできる
import "yuzu441/nogi/package"
のように参照することができる
サンプルコード
go mod init yuzu441/sample
でgo.mod
を生成したという仮定でのサンプル
// service/calc.go package service func Add(x int, y int) int { return x + y } // main.go package main import ( "strconv" "yuzu441/sample/service" ) func main() { result := service.Add(1, 2) println("add result: " + strconv.Itoa(result)) }