GithubHelp home page GithubHelp logo

matthewjones / jwt-cfml Goto Github PK

View Code? Open in Web Editor NEW

This project forked from jcberquist/jwt-cfml

0.0 0.0 0.0 29 KB

CFML (Lucee and ColdFusion) library for encoding and decoding JSON Web Tokens.

License: MIT License

ColdFusion 100.00%

jwt-cfml's Introduction

jwt-cfml

jwt-cfml is a CFML (Lucee and ColdFusion) library for encoding and decoding JSON Web Tokens.

It supports the following algorithms:

  • HS256
  • HS384
  • HS512
  • RS256
  • RS384
  • RS512
  • ES256
  • ES384
  • ES512

In the case of the RS and ES algorithms, asymmetric keys are expected to be provided in unencrypted PEM or JWK format (in the latter case first deserialize the JWK to a CFML struct). When using PEM, private keys need to be encoded in PKCS#8 format.

If your private key is not currently in this format, conversion should be straightforward:

$ openssl pkcs8 -topk8 -nocrypt -in privatekey.pem -out privatekey.pk8

When decoding tokens, either a public key or certificate can be provided. (If a certificate is provided, the public key will be extracted from it.)

You can pre-parse your encoded keys and pass the returned Java classes to the encode() and decode() methods, to avoid having them parsed on every method call. See Parsing Asymmetric Keys below.

Installation

Installation is done via CommandBox:

$ box install jwt-cfml

jwt-cfml will be installed into a jwtcfml package directory by default.

Alternatively the git repository can be cloned into the desired directory.

Standalone

Once the library has been installed, the core jwt component can be instantiated directly:

jwt = new path.to.jwtcfml.models.jwt();

ColdBox Module

You can make use of the library via the injection DSL: jwt@jwtcfml

Usage

Encoding tokens:

payload = {'key': 'value'};
secret = 'secret';
token = jwt.encode(payload, secret, 'HS256');
pemPrivateKey = '
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
';
token = jwt.encode(payload, pemPrivateKey, 'RS256');
jwk = {
    "alg": "RS256",
    "d": "...",
    "dp": "...",
    "dq": "...",
    "e": "AQAB",
    "kty": "RSA",
    "n": "...",
    "p": "...",
    "q": "...",
    "qi": "..."
};
token = jwt.encode(payload, jwk, 'RS256');

When a token is encoded, a header is automatically included containing "typ" set to "JWT" and "alg" set to the passed in algorithm. If you need to add additional headers a fourth argument, headers, is available for this:

token = jwt.encode(payload, pemPrivateKey, 'RS256', {'kid': 'abc123'});

If your token payload contains "iat", "exp", or "nbf" claims, you can set these to CFML date objects, and they will automatically be converted to UNIX timestamps in the generated token for you.

payload = {'iat': now()};
token = jwt.encode(payload, secret, 'HS256');

Decoding tokens:

token = 'eyJ0e...';
secret = 'secret';
payload = jwt.decode(token, secret, 'HS256');
token = 'eyJ0e...';
pemPublicKey = '
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----
';
payload = jwt.decode(token, pemPublicKey, 'RS256');
token = 'eyJ0e...';
pemCertificate = '
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
';
payload = jwt.decode(token, pemCertificate, 'RS256');
token = 'eyJ0e...';
jwk = {
    "e": "AQAB",
    "kty": "RSA",
    "alg": "RS256",
    "n": "...",
    "use": "sig"
}
payload = jwt.decode(token, jwk, 'RS256');

Note: This library does not rely solely on the algorithm specified in the token header. You must specify the allowed algorithms (either as a string or an array) when calling decode(). The algorithm in the token header must match one of the allowed algorithms.

If the decoded payload contains "iat", "exp", or "nbf" claims, they will be automatically converted from UNIX timestamps to CFML date objects for you.

Getting the token header

If you need to get the token header before decoding (e.g. you need a "kid" from it), you can use the jwt.getHeader() method. This will return the token header as a struct.

token = 'eyJ0e...';
header = jwt.getHeader(token);

Token validity

If a token signature is invalid, the jwt.decode() method will throw an error. Further, if the payload contains the registered claim names "iat", "exp", or "nbf", these will be verified as well, (functionally, "iat" and "nbf" are similar).

If you wish to verify other registered claim names (issuer, subject, audience, or JWT ID), you can pass valid claims into the decode method :

claims = {
    "iss": "someissuer",
    "sub": "somesubject",
    "aud": "someaudience", // this can also be an array
    "jti": "somejwtid"
};

payload = jwt.decode(token, pemCertificate, 'RS256', claims);

This argument can also be used to ignore the "iat", "exp", or "nbf" claims or to validate them against a timestamp other than the current time:

claims = {
    // `exp` will be validated against 1 min in the past instead of the current time
    "exp": dateAdd('n', -1, now()),
    // `nbf` will be ignored
    "nbf": false
};

payload = jwt.decode(token, pemCertificate, 'RS256', claims);

Unverified Payload

If you need to get the payload without doing any verification at all you can pass verify=false into the decode method:

jwt.decode(token = token, verify = false);

Parsing Asymmetric Keys

Every time a PEM key or JWK is passed into encode() and decode() it must be converted to binary data and then the appropriate Java class created. You can avoid this (minor) overhead by parsing your key upfront, and then passing the generated Java key class directly into encode() and decode():

pemCertificate = '
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
';
publicKey = jwt.parsePEMEncodedKey(pemCertificate);
payload = jwt.decode(token, publicKey, 'RS256');
jwk = {
    "e": "AQAB",
    "kty": "RSA",
    "alg": "RS256",
    "n": "AN...",
    "use": "sig"
};
publicKey = jwt.parseJWK(jwk);
payload = jwt.decode(token, publicKey, 'RS256');

Acknowledgments

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.