■はじめに
APIなどでJWTを取得する事があります。
その際にそのJWTをデコードして値を操作する必要があるので、ここでは「ライブラリを使用せずに」JWTをデコードする方法を記載します。
※ライブラリ使ってはいけないプロジェクトもあるので。。。
■手順
以下の関数を定義します。
細かい内容はコメントをみてください!!
/// JWT(Json Web Token)のデコード処理
/// - Parameters:
/// - token: JWT
/// - type: デコードタイプ(0: ヘッダーの取得, 1: ペイロードの取得)※引数に指定しなければペイロードが取得される
func jwtDecode(_ token: String, _ type: Int = 1) -> [String: AnyObject]? {
// JWTを「.」で分割して取得したい項目を取得する(0:Header, 1:Payload)
let toDecode = token.components(separatedBy: ".")[type] as String
// JWTでエンコードする際にキャストされる文字列(「-」「+」)をキャスト前に戻す
var stringtoDecode: String = toDecode.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/")
// 文字数に応じて末に「=」を追加する
switch stringtoDecode.utf16.count % 4 {
case 2:
stringtoDecode += "=="
case 3:
stringtoDecode += "="
default:
break
}
// JWTを辞書型にキャストする
guard
let dataToDecode = Data(base64Encoded: stringtoDecode, options: []),
let base64DecodedString = NSString(data: dataToDecode, encoding: String.Encoding.utf8.rawValue),
let data = base64DecodedString.data(using: String.Encoding.utf8.rawValue, allowLossyConversion: true),
let value = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: AnyObject]
else {
// キャストが失敗したらnilを返す
return nil
}
// キャストが正常に完了したらそのデータを返す
return value
}
使い方の説明をする前に、テストでは以下のJWTを利用します。
※こちらのサイト様(https://jwt.io/)のデフォルト値のデータを拝借(感謝!)
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
以下、JWTの値(PAYLOAD)の取得方法です。
let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
print(jwtDecode(jwt))
ちなみに、以下の様に記載しても同じです!!
※第二引数に「1」を入れました(デフォルト値が1なので入れなくてもいいですが。。。)
let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
print(jwtDecode(jwt, 1))
JWTのHEADERを取得したい場合には以下のように記載してください。
※第二引数が「0」です!
let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
print(jwtDecode(jwt, 0))
注意ですが、第二引数に「0」「1」以外を入れても「nil」が返ってくるだけです。