rubyでjwtのエンコードを実装してみるサンプル
JWTを調べたついでにエンコードしてトークンを作成する実装をしてみようと思い、rubyで実装したみた。
素直にgemを使えよ、という話ですが...😅
JWTについて調べたメモは以下の記事をご参考に。 spangled-shalalala.hatenablog.com
JWTのサンプルコード
require 'json' require 'base64' require 'openssl' SECRET_KEY = "secretkey".freeze def urlsafe_encode64(string) Base64.urlsafe_encode64(string).tr('+/', '-_').gsub(/[\n=]/, '') end header = { alg: "HS256", typ: "JWT" }.to_json header_enc = urlsafe_encode64(header) payload = { "loggedInAs": "admin", "iat": 1422779638 }.to_json payload_enc = urlsafe_encode64(payload) message = [header_enc, payload_enc].join(".") sign = OpenSSL::HMAC::digest("sha256", SECRET_KEY, message) token = [header_enc, payload_enc, urlsafe_encode64(sign)].join(".")
urlsafe_encode64のメソッドは ruby-jwt
から引用。
微妙にはまった点は署名部分を OpenSSL::HMAC::hexdigest
でエンコードしていて結果が合わなくて悩んでしまった。
hexdigestは計算結果を16進文字列で返すのでNG。バイナリ文字列で結果を返すdigestで署名するのが正しいというわけですね。当たり前といえば当たり前ですが見落としていたせいで悩んでしまった。
自分で考えた結果よりjwtの署名の理解ができたような気がします!
トークンの結果はこちらのサイトで一致を確認して(あと、jsonはwikipediaに記載のものを使用したのでそちらの記載とも一致を確認)結果を確かめました。
普段、日常業務でここらへんの暗号化とか実装する機会はあまり無いので楽しかった。これを機会に暗号化の本も読んでみたい。
暗号技術はこの本が有名みたいなので仕事帰りに買ってくるかな。