lucid-shopify-session 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +30 -0
- data/lib/lucid-shopify-session.rb +3 -0
- data/lib/lucid/shopify/session.rb +12 -0
- data/lib/lucid/shopify/session/authorise.rb +25 -0
- data/lib/lucid/shopify/session/decode_session_token.rb +45 -0
- data/lib/lucid/shopify/session/middleware.rb +34 -0
- data/lib/lucid/shopify/session/version.rb +9 -0
- metadata +105 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9ab531b412e4121b375dfc46db8194436b0a00f42d7abc5a92424663fc8db1a5
|
4
|
+
data.tar.gz: 174d49b35b6ee27a16c06033950134eca1f1e8b6a9cc0d7d361075108e3b3a31
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e3bb3f3cc25fac5b93c9fe49a64c5bdefcb21c37f439bddfe8c81ed5d698bc52d9fa53f4d1dc04da7aae67bca20c5d60b7af132a65e0d688c6f6d6e3712aa168
|
7
|
+
data.tar.gz: cdd5992a9d7b7cbde6f8af8b237d4d3420eb08026c427bdb4dbdf72b89432344d9935d2c209547e3a5649038752859c1b455bac59d38e2bee747ef8b0fa28613
|
data/README.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
lucid-shopify-session
|
2
|
+
=====================
|
3
|
+
|
4
|
+
This is [Shopify's new cookieless authentication][0] method for embedded apps,
|
5
|
+
which makes use of session tokens provided by App Bridge to identify the shop.
|
6
|
+
Session cookies are no longer viable due to browsers (starting with Safari)
|
7
|
+
disabling third-party cookies by default. It is possible to work around, but
|
8
|
+
quite impractical and harmful to the user experience, so all embedded apps
|
9
|
+
should use this new method going forward.
|
10
|
+
|
11
|
+
This method also replaces CSRF tokens, as the JWT provides the same protection
|
12
|
+
considering that the signed JWT must originate from the Shopify admin (with the
|
13
|
+
shared secret), so authenticated requests cannot be forged.
|
14
|
+
|
15
|
+
[0]: https://shopify.dev/tools/app-bridge/authentication
|
16
|
+
|
17
|
+
|
18
|
+
Installation
|
19
|
+
------------
|
20
|
+
|
21
|
+
Add the gem to your ‘Gemfile’:
|
22
|
+
|
23
|
+
gem 'lucid-shopify'
|
24
|
+
gem 'lucid-shopify-session'
|
25
|
+
|
26
|
+
|
27
|
+
Usage
|
28
|
+
-----
|
29
|
+
|
30
|
+
_WIP_
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lucid
|
4
|
+
module Shopify
|
5
|
+
module Session
|
6
|
+
autoload :Authorise, 'lucid/shopify/session/authorise'
|
7
|
+
autoload :DecodeSessionToken, 'lucid/shopify/session/decode_session_token'
|
8
|
+
autoload :Middleware, 'lucid/shopify/session/middleware'
|
9
|
+
autoload :VERSION, 'lucid/shopify/session/version'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'lucid-shopify-session'
|
5
|
+
|
6
|
+
module Lucid
|
7
|
+
module Shopify
|
8
|
+
module Session
|
9
|
+
class Authorise
|
10
|
+
UnauthorisedError = Class.new(Error)
|
11
|
+
|
12
|
+
# @param env [Hash]
|
13
|
+
#
|
14
|
+
# @raise [UnauthorisedError]
|
15
|
+
def call(env)
|
16
|
+
session_token = env['HTTP_AUTHORIZATION']&.[](/Bearer (\S+)/, 1) || ''
|
17
|
+
|
18
|
+
env['lucid-shopify-session.shop'] = DecodeSessionToken.new.(session_token)
|
19
|
+
rescue DecodeSessionToken::Error
|
20
|
+
raise UnauthorisedError
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'lucid-shopify'
|
4
|
+
require 'jwt'
|
5
|
+
|
6
|
+
module Lucid
|
7
|
+
module Shopify
|
8
|
+
module Session
|
9
|
+
class DecodeSessionToken
|
10
|
+
Error = Class.new(Error)
|
11
|
+
|
12
|
+
# @param token [String]
|
13
|
+
#
|
14
|
+
# @return [String] the *.myshopify.com domain of the authenticated shop
|
15
|
+
#
|
16
|
+
# @raise [Error]
|
17
|
+
def call(token)
|
18
|
+
payload, _ = JWT.decode(token, Shopify.config.shared_secret, true, algorithm: 'HS256')
|
19
|
+
|
20
|
+
raise Error unless valid?(payload)
|
21
|
+
|
22
|
+
myshopify_domain(payload)
|
23
|
+
rescue JWT::DecodeError
|
24
|
+
raise Error
|
25
|
+
end
|
26
|
+
|
27
|
+
# @param payload [Hash]
|
28
|
+
#
|
29
|
+
# @return [String]
|
30
|
+
private def myshopify_domain(payload)
|
31
|
+
payload['dest'].sub('https://', '')
|
32
|
+
end
|
33
|
+
|
34
|
+
# @param payload [Hash]
|
35
|
+
#
|
36
|
+
# @return [Boolean]
|
37
|
+
private def valid?(payload)
|
38
|
+
return false unless payload['aud'] == Shopify.config.api_key
|
39
|
+
return false unless payload['iss'].start_with?(payload['dest'])
|
40
|
+
return true
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'lucid-shopify-session'
|
5
|
+
|
6
|
+
module Lucid
|
7
|
+
module Shopify
|
8
|
+
module Session
|
9
|
+
class Middleware
|
10
|
+
# @param app [#call]
|
11
|
+
def initialize(app)
|
12
|
+
@app = app
|
13
|
+
end
|
14
|
+
|
15
|
+
# @param env [Hash]
|
16
|
+
#
|
17
|
+
# @param [Array<Integer, Hash{String => String}, Array<String>]
|
18
|
+
def call(env)
|
19
|
+
Authorise.new.(env)
|
20
|
+
|
21
|
+
@app.call(env)
|
22
|
+
rescue UnauthorisedError
|
23
|
+
Rack::Response.new do |res|
|
24
|
+
res.status = 401
|
25
|
+
res.set_header('Content-Type', 'application/json')
|
26
|
+
res.write({
|
27
|
+
error: 'Invalid session token',
|
28
|
+
}.to_json)
|
29
|
+
end.to_a
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lucid-shopify-session
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kelsey Judson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-12-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.9'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.9'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rubocop
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.89'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.89'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: jwt
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.2'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.2'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: lucid-shopify
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.64'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.64'
|
69
|
+
description:
|
70
|
+
email: kelsey@kelseyjudson.dev
|
71
|
+
executables: []
|
72
|
+
extensions: []
|
73
|
+
extra_rdoc_files: []
|
74
|
+
files:
|
75
|
+
- README.md
|
76
|
+
- lib/lucid-shopify-session.rb
|
77
|
+
- lib/lucid/shopify/session.rb
|
78
|
+
- lib/lucid/shopify/session/authorise.rb
|
79
|
+
- lib/lucid/shopify/session/decode_session_token.rb
|
80
|
+
- lib/lucid/shopify/session/middleware.rb
|
81
|
+
- lib/lucid/shopify/session/version.rb
|
82
|
+
homepage: https://github.com/kj/lucid-shopify-session
|
83
|
+
licenses:
|
84
|
+
- ISC
|
85
|
+
metadata: {}
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options: []
|
88
|
+
require_paths:
|
89
|
+
- lib
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
requirements: []
|
101
|
+
rubygems_version: 3.1.4
|
102
|
+
signing_key:
|
103
|
+
specification_version: 4
|
104
|
+
summary: Shopify client library session token helpers for embedded apps
|
105
|
+
test_files: []
|