Class: Peatio::Auth::JWTAuthenticator

Inherits:
Object
  • Object
show all
Defined in:
lib/peatio/auth/jwt_authenticator.rb

Overview

JWTAuthenticator used to authenticate user using JWT.

It allows configuration of JWT verification through following ENV variables (all optional):

  • JWT_ISSUER

  • JWT_AUDIENCE

  • JWT_ALGORITHM (default: RS256)

  • JWT_DEFAULT_LEEWAY

  • JWT_ISSUED_AT_LEEWAY

  • JWT_EXPIRATION_LEEWAY

  • JWT_NOT_BEFORE_LEEWAY

Examples:

Token validation

rsa_private = OpenSSL::PKey::RSA.generate(2048)
rsa_public = rsa_private.public_key

payload = {
  iat: Time.now.to_i,
  exp: (Time.now + 60).to_i,
  sub: "session",
  iss: "barong",
  aud: [
    "peatio",
    "barong",
  ],
  jti: "BEF5617B7B2762DDE61702F5",
  uid: "TEST123",
  email: "[email protected]",
  role: "admin",
  level: 4,
  state: "active",
}

token = JWT.encode(payload, rsa_private, "RS256")

auth = Peatio::Auth::JWTAuthenticator.new(rsa_public)
auth.authenticate!("Bearer #{token}")

See Also:

Instance Method Summary collapse

Constructor Details

#initialize(public_key, private_key = nil) ⇒ JWTAuthenticator

Creates new authenticator with given public key.

Parameters:

  • public_key (OpenSSL::PKey::PKey)

    Public key object to verify signature.

  • private_key (OpenSSL::PKey::PKey) (defaults to: nil)

    Optional private key that used only to encode new tokens.



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/peatio/auth/jwt_authenticator.rb', line 52

def initialize(public_key, private_key = nil)
  @public_key = public_key
  @private_key = private_key

  @verify_options = {
    verify_expiration: true,
    verify_not_before: true,
    iss: ENV["JWT_ISSUER"],
    verify_iss: !ENV["JWT_ISSUER"].nil?,
    verify_iat: true,
    verify_jti: true,
    aud: ENV["JWT_AUDIENCE"].to_s.split(",").reject(&:empty?),
    verify_aud: !ENV["JWT_AUDIENCE"].nil?,
    sub: "session",
    verify_sub: true,
    algorithms: [ENV["JWT_ALGORITHM"] || "RS256"],
    leeway: ENV["JWT_DEFAULT_LEEWAY"].yield_self { |n| n.to_i unless n.nil? },
    iat_leeway: ENV["JWT_ISSUED_AT_LEEWAY"].yield_self { |n| n.to_i unless n.nil? },
    exp_leeway: ENV["JWT_EXPIRATION_LEEWAY"].yield_self { |n| n.to_i unless n.nil? },
    nbf_leeway: ENV["JWT_NOT_BEFORE_LEEWAY"].yield_self { |n| n.to_i unless n.nil? },
  }.compact

  @encode_options = {
    algorithm: @verify_options[:algorithms].first,
  }.compact
end

Instance Method Details

#authenticate!(token) ⇒ Hash

Decodes and verifies JWT. Returns payload from JWT or raises an exception

Parameters:

  • token (String)

    Token string. Must start from "Bearer ".

Returns:

  • (Hash)

    Payload Hash from JWT without any changes.

Raises:



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/peatio/auth/jwt_authenticator.rb', line 86

def authenticate!(token)
  token_type, token_value = token.to_s.split(" ")

  unless token_type == "Bearer"
    raise(Peatio::Auth::Error, "Token type is not provided or invalid.")
  end

  decode_and_verify_token(token_value)
rescue => error
  case error
  when Peatio::Auth::Error
    raise(error)
  else
    raise(Peatio::Auth::Error, error.message)
  end
end

#encode(payload) ⇒ String

Encodes given payload and produces JWT.

Parameters:

  • payload (String, Hash)

    Payload to encode.

Returns:

  • (String)

    JWT token string.

Raises:

  • (ArgumentError)

    If no private key was passed to constructor.



109
110
111
112
113
# File 'lib/peatio/auth/jwt_authenticator.rb', line 109

def encode(payload)
  raise(::ArgumentError, "No private key given.") if @private_key.nil?

  JWT.encode(payload, @private_key, @encode_options[:algorithm])
end