jwt_sessions 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5168d7361bdf008db2c14204b698bed8926aa0fc
4
- data.tar.gz: 7a218c9787fef9375a260064adaaf69f31d53e78
3
+ metadata.gz: 143a1452f628f1d201801cc8b7b4855de56479fb
4
+ data.tar.gz: e648fe573c4239e2359d808b5fb93e58d253cf59
5
5
  SHA512:
6
- metadata.gz: 5646630d2e046bf3f6519f384e21306ba109127f53cf831d06164e39d8805396f7a3e561a3afe702c647308faca3cee949300726e3e0134e3fb24563c1330981
7
- data.tar.gz: 902ef70ff8adfe56771ebbab3f06b330bf762a81fc13e9c555df0eaab4b8dfd7ca30b95d84355cfaf4bf11c3508c0e015bcba744bf7eb39095d7c4f6b3b9f4c1
6
+ metadata.gz: d81c0bda06caebed8b38ca9649de98c3e5680859beb7059fd5f0534239f1aeb5b859c0e6f0582bb4585de44b7eef83136fa735d1ac2f7fa6107949e82dd777bb
7
+ data.tar.gz: 7e717dc3a0326c81239d1ce12937182bcc5f7d59df884f9eb4e7513f7a398b8c42984b97865e8bdc6f1a3efc75e8b8c96225b04ff76c64adf44f95508cdc57e7
data/README.md CHANGED
@@ -1,8 +1,29 @@
1
1
  # jwt_sessions
2
2
  [![Gem Version](https://badge.fury.io/rb/jwt_sessions.svg)](https://badge.fury.io/rb/jwt_sessions)
3
+ [![Maintainability](https://api.codeclimate.com/v1/badges/53de11b8334933b1c0ef/maintainability)](https://codeclimate.com/github/tuwukee/jwt_sessions/maintainability)
4
+ [![Build Status](https://travis-ci.org/tuwukee/jwt_sessions.svg?branch=master)](https://travis-ci.org/tuwukee/jwt_sessions)
3
5
 
4
6
  XSS/CSRF safe JWT auth designed for SPA
5
7
 
8
+ ## Table of Contents
9
+
10
+ - [Synopsis](#synopsis)
11
+ - [Installation](#installation)
12
+ - [Getting Started](#getting-started)
13
+ * [Rails integration](#rails-integration)
14
+ * [Non-Rails usage](#non-rails-usage)
15
+ - [Configuration](#configuration)
16
+ + [Redis](#redis)
17
+ + [JWT encryption](#jwt-encryption)
18
+ + [Request headers and cookies names](#request-headers-and-cookies-names)
19
+ + [Expiration time](#expiration-time)
20
+ + [CSRF and cookies](#csrf-and-cookies)
21
+ + [Refresh token hijack protection](#refresh-token-hijack-protection)
22
+ - [Examples](#examples)
23
+ - [TODO](#todo)
24
+ - [Contributing](#contributing)
25
+ - [License](#license)
26
+
6
27
  ## Synopsis
7
28
 
8
29
  Main goal of this gem is to provide configurable, manageable, and safe stateful sessions based on JSON Web Tokens.
@@ -60,7 +81,8 @@ JWTSessions.encryption_key = Rails.application.secrets.secret_jwt_encryption_key
60
81
  ```
61
82
 
62
83
  Generate access/refresh/csrf tokens with a custom payload. \
63
- The payload will be available in the controllers once the access (or refresh) token is authorized.
84
+ The payload will be available in the controllers once the access (or refresh) token is authorized. \
85
+ Access/refresh tokens contain expiration time in their payload. Yet expiration times are also added to the output just in case.
64
86
 
65
87
  ```ruby
66
88
  > payload = { user_id: user.id }
@@ -72,7 +94,9 @@ The payload will be available in the controllers once the access (or refresh) to
72
94
  > session.login
73
95
  => {:csrf=>"BmhxDRW5NAEIx...",
74
96
  :access=>"eyJhbGciOiJIUzI1NiJ9...",
75
- :refresh=>"eyJhbGciOiJIUzI1NiJ9..."}
97
+ :access_expires_at=>"..."
98
+ :refresh=>"eyJhbGciOiJIUzI1NiJ9...",
99
+ :refresh_expires_at=>"..."}
76
100
  ```
77
101
 
78
102
  You can build login controller to receive access, refresh and csrf tokens in exchange for user's login/password. \
@@ -185,7 +209,7 @@ def request_method
185
209
  end
186
210
  ```
187
211
 
188
- Example Sinatra app.
212
+ Example Sinatra app. \
189
213
  NOTE: Since rack updates HTTP headers by using `HTTP_` prefix, upcasing and using underscores for sake of simplicity JWTSessions tokens header names are converted to rack-style in this example.
190
214
 
191
215
  ```ruby
@@ -231,7 +255,7 @@ class SimpleApp < Sinatra::Base
231
255
  session.refresh(found_token).to_json
232
256
  end
233
257
 
234
- # GEY /payload
258
+ # GET /payload
235
259
  # authorization: Bearer ...
236
260
  get '/payload' do
237
261
  authorize_access_request!
@@ -310,6 +334,11 @@ session = JwtSessions::Session.new(payload: payload)
310
334
  session.refresh(refresh_token) { |refresh_token_uid, access_token_expiration| ... }
311
335
  ```
312
336
 
337
+ ## Examples
338
+
339
+ [Rails API](test/support/dummy_api) \
340
+ [Sinatra API](test/support/dummy_sinatra_api)
341
+
313
342
  ## TODO
314
343
 
315
344
  Ability to specify public and private keys for RSA/EDCSA/EDDSA, there are no default values for keys. \
@@ -1,12 +1,13 @@
1
1
  module JWTSessions
2
2
  class AccessToken
3
- attr_reader :token, :payload, :uid, :expiration, :csrf
3
+ attr_reader :token, :payload, :uid, :expiration, :csrf, :store
4
4
 
5
5
  def initialize(csrf, payload, store, uid = SecureRandom.uuid, expiration = JWTSessions.access_expiration)
6
6
  @csrf = csrf
7
7
  @uid = uid
8
8
  @expiration = expiration
9
9
  @payload = payload
10
+ @store = store
10
11
  @token = Token.encode(payload.merge(uid: uid, exp: expiration.to_i))
11
12
  end
12
13
 
@@ -84,7 +84,11 @@ module JWTSessions
84
84
  end
85
85
 
86
86
  def tokens_hash
87
- { csrf: csrf_token, access: access_token, refresh: refresh_token }
87
+ { csrf: csrf_token,
88
+ access: access_token,
89
+ access_expires_at: Time.at(@_access.expiration.to_i),
90
+ refresh: refresh_token,
91
+ refresh_expires_at: Time.at(@_refresh.expiration.to_i) }
88
92
  end
89
93
 
90
94
  def check_refresh_on_time
@@ -111,7 +115,11 @@ module JWTSessions
111
115
  end
112
116
 
113
117
  def create_refresh_token
114
- @_refresh = RefreshToken.create(@_csrf.encoded, @_access.uid, @_access.expiration, store, @refresh_payload)
118
+ @_refresh = RefreshToken.create(@_csrf.encoded,
119
+ @_access.uid,
120
+ @_access.expiration,
121
+ store,
122
+ @refresh_payload)
115
123
  @refresh_token = @_refresh.token
116
124
  end
117
125
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JWTSessions
4
- VERSION = '1.0.1'
4
+ VERSION = '1.0.2'
5
5
  end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minitest/autorun'
4
+ require 'jwt_sessions'
5
+
6
+ class TestAccessToken < Minitest::Test
7
+ attr_reader :access_token, :uid
8
+
9
+ def setup
10
+ JWTSessions.encryption_key = 'secret key'
11
+ @payload = { user_id: 1 }
12
+ @csrf = JWTSessions::CSRFToken.new
13
+ @uid = SecureRandom.uuid
14
+ @access_token = JWTSessions::AccessToken.create(@csrf.encoded,
15
+ @payload,
16
+ JWTSessions.token_store)
17
+ end
18
+
19
+ def test_csrf
20
+ token = JWTSessions.token_store.fetch_access(access_token.uid)
21
+ assert_equal token[:csrf], access_token.csrf
22
+ access_token.destroy
23
+ end
24
+
25
+ def test_destroy
26
+ JWTSessions::AccessToken.destroy(access_token.uid, JWTSessions.token_store)
27
+ token = JWTSessions.token_store.fetch_access(access_token.uid)
28
+ assert_equal({}, token)
29
+ end
30
+ end
@@ -7,7 +7,7 @@ class TestRefreshToken < Minitest::Test
7
7
  attr_reader :csrf, :token, :access_uid
8
8
 
9
9
  def setup
10
- JWTSessions.encryption_key = '65994c7b523a3232e7aba54d8cbf'
10
+ JWTSessions.encryption_key = 'secure encryption'
11
11
  @access_uid = SecureRandom.uuid
12
12
  @csrf = JWTSessions::CSRFToken.new
13
13
  @token = JWTSessions::RefreshToken.create(@csrf.encoded,
@@ -5,11 +5,11 @@ require 'jwt_sessions'
5
5
 
6
6
  class TestSession < Minitest::Test
7
7
  attr_reader :session, :payload, :tokens
8
- EXPECTED_KEYS = [:access, :csrf, :refresh].freeze
8
+ EXPECTED_KEYS = %i[access access_expires_at csrf refresh refresh_expires_at].freeze
9
9
 
10
10
  def setup
11
- JWTSessions.encryption_key = '65994c7b523a3232e7aba54d8cbf'
12
- @payload = { test: 'test' }
11
+ JWTSessions.encryption_key = 'encrypted'
12
+ @payload = { test: 'secret' }
13
13
  @session = JWTSessions::Session.new(payload: payload)
14
14
  @tokens = session.login
15
15
  end
@@ -7,13 +7,15 @@ class TestToken < Minitest::Test
7
7
  attr_reader :payload
8
8
 
9
9
  def setup
10
- JWTSessions.encryption_key = '65994c7b523a3232e7aba54d8cbf'
11
- @payload = { 'user_id' => 1 }
10
+ JWTSessions.encryption_key = 'super secret'
11
+ @payload = { 'user_id' => 1, 'secret' => 'mystery' }
12
12
  end
13
13
 
14
14
  def test_valid_token_decode
15
15
  token = JWTSessions::Token.encode(payload)
16
- assert_equal payload['user_id'], JWTSessions::Token.decode(token).first['user_id']
16
+ decoded = JWTSessions::Token.decode(token).first
17
+ assert_equal payload['user_id'], decoded['user_id']
18
+ assert_equal payload['secret'], decoded['secret']
17
19
  end
18
20
 
19
21
  def test_invalid_token_decode
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jwt_sessions
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yulia Oletskaya
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-17 00:00:00.000000000 Z
11
+ date: 2018-04-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jwt
@@ -38,6 +38,34 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.16'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.16'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '5.11'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '5.11'
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: pry
43
71
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +80,20 @@ dependencies:
52
80
  - - "~>"
53
81
  - !ruby/object:Gem::Version
54
82
  version: '0.11'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '10.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '10.0'
55
97
  description: XSS/CSRF safe JWT auth designed for SPA
56
98
  email: yulia.oletskaya@gmail.com
57
99
  executables: []
@@ -71,6 +113,7 @@ files:
71
113
  - lib/jwt_sessions/session.rb
72
114
  - lib/jwt_sessions/token.rb
73
115
  - lib/jwt_sessions/version.rb
116
+ - test/units/jwt_sessions/test_access_token.rb
74
117
  - test/units/jwt_sessions/test_csrf_token.rb
75
118
  - test/units/jwt_sessions/test_refresh_token.rb
76
119
  - test/units/jwt_sessions/test_session.rb
@@ -102,6 +145,7 @@ specification_version: 4
102
145
  summary: JWT Sessions
103
146
  test_files:
104
147
  - test/units/test_jwt_sessions.rb
148
+ - test/units/jwt_sessions/test_access_token.rb
105
149
  - test/units/jwt_sessions/test_csrf_token.rb
106
150
  - test/units/jwt_sessions/test_refresh_token.rb
107
151
  - test/units/jwt_sessions/test_session.rb