kylef / JSONWebToken.swift

Swift implementation of JSON Web Token (JWT).
http://jwt.io
BSD 2-Clause "Simplified" License
762 stars 226 forks source link

Difference between JWT Tokens #73

Closed SpacyRicochet closed 7 years ago

SpacyRicochet commented 7 years ago

I'm currently trying to generate a simple JWT, where the only payload is a expiration date. However, my implementation when trying to use this library appears to generate a different token than when when I use https://github.com/yourkarma/JWT or when checking jwt.io (these two are consistent with each other).

Using the CocoaPods Playgrounds gem (gem install cocoapods-playgrounds), I tried out both of them, using equivalent implementations (as far as I can tell).

JSONWebToken

// After installing the gem, use `pod playground JSONWebToken` to generate a playground quickly.

//: Please build the scheme 'JWTPlayground' first
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

import JWT

let secret = "DevelopmentTestJWTSecret1"

var claims = ClaimSet()
claims.expiration = Date.distantFuture

let token = JWT.encode(claims: claims, algorithm: .hs256(secret.data(using: .utf8)!))
print(token)
// prints eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjY0MDkyMjExMjAwfQ.uk571j2rhEXAO_5K2AjGKLgPd6WaIAUVAioontTdVIs

Your Karma's JWT

// After installing the gem, use `pod playground JWT` to generate a playground quickly.

//: Please build the scheme 'JWTPlayground' first
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

import JWT

let secret = "DevelopmentTestJWTSecret1"
let algorithm = JWTAlgorithmFactory.algorithm(byName: "HS256")

var claims = JWTClaimsSet()
claims.expirationDate = Date.distantFuture

let token = JWT.encode(claims, withSecret: secret, algorithm: JWTAlgorithmHS256())
print(token!)
// prints eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjY0MDkyMjExMjAwfQ.qOIoSj36uxELKwl3uejese_IBpAeEw36WQ9mmeOYk0A

jwt.io

Filling in the above settings in jwt.io, gives me the following key, which is equivalent to JWT's result;

// prints eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjY0MDkyMjExMjAwfQ.qOIoSj36uxELKwl3uejese_IBpAeEw36WQ9mmeOYk0A
screen shot 2017-05-31 at 19 05 58

(Take care with the order of typ and alg in the website. By default, they appear to show it the other way around.)


I'm thinking I'm filling in something wrong, but I can't spot it.

Any idea why the result for JSONWebToken is different?

SpacyRicochet commented 7 years ago

Ah, I found it. Because encode(:,:) uses a plain dictionary, it doesn't enforce any particular order for that library. What actually gets encoded is:

{"alg":"HS256","typ":"JWT"}

This results in the expected payload according to JWT.io. So, no errors here!