ゆずめも

メモ的なブログです。主に勉強した事について書いてます。

jwtについて軽く調べた

仕事でjwt使う〜?って話になったので雰囲気しかしらなかったので調べてみた

jwtとは

  • <header>.<payload>.<sign>で構成されている
    • 各要素が.(dot)で区切られている
  • header
    • {"typ": "JWT", "alg": "HS256"}
      • typはJWTの文字列でjwtで有ることを表していて
      • algは署名アルゴリズム
        • HS256はHMAC SHA-256を表している
  • 関連仕様
    • JSON Web Signature(JWS)
    • JSON Web Encryption(JWE)

よくある作り方

  1. headerをbase64url encode
  2. payloadをbase64url encode
  3. .で結合
  4. 結合した文字列でhashを取る
  5. ハッシュ値を文字列の末尾に結合する

気になったこと

  • header, payloadはbase64エンコードをしているだけだが秘密鍵がもれない限りは同じ署名を作成できない > 改竄検出
  • 鍵のローテション
    • 一定時間で変更しないといけない
    • awsだとkms(Key Management Service)とか使うのか?
      • とりあえず手作業だと無理
  • cookieの不安
    • 4096Bが限界なのでbase64で1.2倍になると考えるとペイロードが多くなれば使えない?
    • ブラウザのSession Storageなどを使う方法もあるがcookieと違い自動的には送出されない
  • alg:none脆弱性
    • jwtはalg:noneにすると署名検証を行わないことが可能
    • ライブラリとかを使用する場合は注意必要
  • tokenの流出時について
    • tokenを直接無効はできない
      • 該当アカウントを一時的に無効化(tokenのexpまで)
      • 該当tokenのRefresh 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だと以下のように書けるのでxabというプロパティを持っていることがわかる(例はtypescript)

type Props = {
  x: {a: number, b: number}
  y: number
}
function MyComponent(props: Props) {}

Flow

Flowはfacebook製のOSSOCamlで実装されている

https://flow.org/

最近のは使ってないのでよくわかってないが、前に使った経験的にはtsより推論が賢かったイメージがある

Reactをよくある構成で使う時はflow-typedで型が見つかるが、ちょっと珍しいライブラリとかだと型定義自作する所から始まるイメージ 記事書きながら見てみたらめっちゃ増えてたけどtsに比べるとちょっと辛そう

github.com

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.modmodule項目とwikiを見て

github.com

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がないのでパッケージ名の指定をどうするのかがわからなかったが、githubwikiを見ていると答えが書いてあった

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/samplego.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))
}