improve cookie- based session with decorator pattern · @ confoo montreal 2018-03-08 by jian...

91
Improve Cookie- based Session with Decorator Pattern @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1

Upload: others

Post on 23-Sep-2020

4 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Improve Cookie-based Sessionwith Decorator

Pattern@ ConFoo Montreal 2018-03-08

by Jian Weihang

Improve Cookie-based Session with Decorator Pattern 1

Page 2: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Bonjour!Improve Cookie-based Session with Decorator Pattern 2

Page 3: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

墋簏膠Jian Weihang

Improve Cookie-based Session with Decorator Pattern 3

Page 4: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

@tonytonyjan

Improve Cookie-based Session with Decorator Pattern 4

Page 5: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Taiwan

Improve Cookie-based Session with Decorator Pattern 5

Page 6: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Improve Cookie-based Session with Decorator Pattern 6

Page 7: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Improve Cookie-based Session with Decorator Pattern 7

Page 8: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Improve Cookie-based Session with Decorator Pattern 8

Page 9: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

$ gem install taiwan

Improve Cookie-based Session with Decorator Pattern 9

Page 10: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Tech Leader

Improve Cookie-based Session with Decorator Pattern 10

Page 11: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Ruby Developersince 2010

Improve Cookie-based Session with Decorator Pattern 11

Page 12: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Maintainerof exif and jaro_winkler

Improve Cookie-based Session with Decorator Pattern 12

Page 13: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Published a bookin 2015

Improve Cookie-based Session with Decorator Pattern 13

Page 14: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Improve Cookie-based Sessionwith Decorator

PatternImprove Cookie-based Session with Decorator Pattern 14

Page 15: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Outline• Introduction of Decorator Pattern

• Security of Rack::Session::Cookie

• Encryption of Rack::Session::Cookie

Improve Cookie-based Session with Decorator Pattern 15

Page 16: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Decorator Pattern

Improve Cookie-based Session with Decorator Pattern 16

Page 17: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Decorator Pattern

Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.— Design Patterns by the Gang of Four

Improve Cookie-based Session with Decorator Pattern 17

Page 18: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Using Inheritanceclass CoffeeWithSugar < Coffee def cost super + 0.2 endend

class CoffeeWithMilkAndSugar < Coffee def cost super + 0.4 + 0.2 endend

Improve Cookie-based Session with Decorator Pattern 18

Page 19: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

What's the problem?• Cannot customize during runtime.

• Cannot control how and when to decorate a component.

• ex. double milk?

• It is tightly coupled.

Improve Cookie-based Session with Decorator Pattern 19

Page 20: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

What's the problem?• Cannot customize during runtime.

• Cannot control how and when to decorate a component.

• ex. double milk?

• It is tightly coupled.

Improve Cookie-based Session with Decorator Pattern 20

Page 21: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

What's the problem?• Cannot customize during runtime.

• Cannot control how and when to decorate a component.

• ex. double milk?

• It is tightly coupled.

Improve Cookie-based Session with Decorator Pattern 21

Page 22: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Decorator Pattern in Rubyclass Milk def initialize(coffee); @coffee = coffee end def cost; @coffee.cost + 0.4 endend

class Sugar def initialize(coffee); @coffee = coffee end def cost; @coffee.cost + 0.2 endend

coffee = Coffee.new # coffee.cost = 2.0Sugar.new(Milk.new(coffee)).cost # 2.6Sugar.new(Sugar.new(coffee)).cost # 2.4

Improve Cookie-based Session with Decorator Pattern 22

Page 23: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Benefits• Plain Old Ruby Object.

• Can be wrapped infinitely.

• Can use same decorator more than once on component.

• Can customize in runtime.

Improve Cookie-based Session with Decorator Pattern 23

Page 24: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Benefits• Plain Old Ruby Object.

• Can be wrapped infinitely.

• Can use same decorator more than once on component.

• Can customize in runtime.

Improve Cookie-based Session with Decorator Pattern 24

Page 25: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Benefits• Plain Old Ruby Object.

• Can be wrapped infinitely.• Can use same decorator more than once on component.

• Can customize in runtime.

Improve Cookie-based Session with Decorator Pattern 25

Page 26: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Benefits• Plain Old Ruby Object.

• Can be wrapped infinitely.

• Can use same decorator more than once on component.

• Can customize in runtime.

Improve Cookie-based Session with Decorator Pattern 26

Page 27: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

class Additive def initialize(coffee) @coffee = coffee end

def cost raise NotImplementedError endend

class Salt < Additive def cost @coffee.cost + 0.1 endend

Improve Cookie-based Session with Decorator Pattern 27

Page 28: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Rack

Improve Cookie-based Session with Decorator Pattern 28

Page 29: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Is Rack::Session::Cookie

secure?

Improve Cookie-based Session with Decorator Pattern 29

Page 30: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Simple HTTP Serverrequire 'rack'

app = lambda do |env| session = env['rack.session'] session[:name] = 'tonytonyjan' session[:age] = 28 [200, {}, ['it works']]end

app = Rack::Builder.app(app) do use Rack::Session::Cookie, secret: 'secret'end

Rack::Handler::WEBrick.run app, Port: ARGV[0]

Improve Cookie-based Session with Decorator Pattern 30

Page 31: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Experiment

Improve Cookie-based Session with Decorator Pattern 31

Page 32: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

DecodeMarshal.load( Base64.decode64( URI.decode_www_form_component(cookie) .split('--') .first ))

Improve Cookie-based Session with Decorator Pattern 32

Page 33: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Structure of Rack Cookie Session+------------- uri encode --------------+| +------ base64 ------+ +- hex -+ || | +- Marshal.dump -+ | | | || | | object | | "--" | mac | || | +----------------+ | | | || +--------------------+ +-------+ |+---------------------------------------+

Improve Cookie-based Session with Decorator Pattern 33

Page 34: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Decode and Verifydef decode_cookie(cookie, secret) cookie = URI.decode_www_form_component(cookie) data, hmac = cookie.split('--') computed_hmac = OpenSSL::HMAC.hexdigest( OpenSSL::Digest::SHA1.new, secret, data ) raise 'invalid hmac' unless computed_hmac == hmac Marshal.load(Base64.decode64(data))end

Improve Cookie-based Session with Decorator Pattern 34

Page 35: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Is Rack::Session::Cookie

secure?

Improve Cookie-based Session with Decorator Pattern 35

Page 36: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Not Exactly

Improve Cookie-based Session with Decorator Pattern 36

Page 37: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Rack::Session::Cookie• Sign with HMAC-SHA1.

• No encryption.

Improve Cookie-based Session with Decorator Pattern 37

Page 38: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Rack::Session::Cookie• Sign with HMAC-SHA1.

• No encryption.

Improve Cookie-based Session with Decorator Pattern 38

Page 39: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Rack::Session::Cookie• Sign with HMAC-SHA1.

• No encryption.

Improve Cookie-based Session with Decorator Pattern 39

Page 40: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Sinatra

Improve Cookie-based Session with Decorator Pattern 40

Page 41: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Sinatra Official Document

Improve Cookie-based Session with Decorator Pattern 41

Page 42: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

require 'sinatra'

set :sessions, trueset :session_secret, 'set secret'

get '/' do session = env['rack.session'] session[:name] = 'tonytonyjan' session[:age] = 28 'Hello world!'end

Improve Cookie-based Session with Decorator Pattern 42

Page 43: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Experiment

Improve Cookie-based Session with Decorator Pattern 43

Page 44: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Improve Cookie-based Session with Decorator Pattern 44

Page 45: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Improve Cookie-based Session with Decorator Pattern 45

Page 46: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Rails

Improve Cookie-based Session with Decorator Pattern 46

Page 47: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Convention over Configuration

Improve Cookie-based Session with Decorator Pattern 47

Page 48: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Structure of Rails Cookie+-------------------- uri encode -------------------+| +------------ base64 ------------+ +- hex -+ || | +- base64 -+ +- base64 -+ | | | || | | JSON | "--" | iv | | "--" | mac | || | +----------+ +----------+ | | | || +--------------------------------+ +-------+ |+---------------------------------------------------+

Improve Cookie-based Session with Decorator Pattern 48

Page 49: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Decode with ActiveSupportrequire 'uri'require 'json'require 'active_support'

def verify_and_decrypt_session_cookie(cookie, secret_key_base) cookie = URI.decode_www_form_component(cookie) salt = 'encrypted cookie' signed_salt = 'signed encrypted cookie' key_generator = ActiveSupport::KeyGenerator.new(secret_key_base, iterations: 1000) secret = key_generator.generate_key(salt)[0, ActiveSupport::MessageEncryptor.key_len] sign_secret = key_generator.generate_key(signed_salt) encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret, serializer: JSON) encryptor.decrypt_and_verify(cookie)end

Pure Ruby Version: https://goo.gl/vuQPkrImprove Cookie-based Session with Decorator Pattern 49

Page 50: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Encryption in Rack::Session::Cookie

Improve Cookie-based Session with Decorator Pattern 50

Page 51: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

require 'rack'require 'action_dispatch'

secret_key_base = '...secret_key_base...'key_generator = ActiveSupport::KeyGenerator.new(secret_key_base, iterations: 1000)

app = lambda do |env| env['action_dispatch.secret_key_base'] = secret_key_base env['action_dispatch.cookies_serializer'] = :json env['action_dispatch.signed_cookie_salt'] = 'signed cookie' env['action_dispatch.encrypted_cookie_salt'] = 'encrypted cookie' env['action_dispatch.encrypted_signed_cookie_salt'] = 'signed encrypted cookie' env['action_dispatch.key_generator'] = key_generator session = env['rack.session'] session[:name] = 'tonytonyjan' session[:age] = 28 [200, {}, ['it works']]end

app = Rack::Builder.app(app) do use ActionDispatch::Cookies use ActionDispatch::Session::CookieStore, key: '_myapp_session'end

Improve Cookie-based Session with Decorator Pattern 51

Page 52: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Cons• ActionDispatch is fat.

• Stack too deep.

Improve Cookie-based Session with Decorator Pattern 52

Page 53: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Cons• ActionDispatch is fat.• Stack too deep.

Improve Cookie-based Session with Decorator Pattern 53

Page 54: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Cons• ActionDispatch is fat.• Stack too deep.

Improve Cookie-based Session with Decorator Pattern 54

Page 55: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Custom Codercoder.respond_to?(:encode) # => truecoder.respond_to?(:decode) # => true

app = Rack::Builder.app(app) do use(Rack::Session::Cookie, coder: coder, let_coder_handle_secure_encoding: true )end

Improve Cookie-based Session with Decorator Pattern 55

Page 56: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Custom Coderclass CustomCoder def encode(obj) Base64.encode64(Marshal.dump(obj)) end

def decode(obj) Marshal.decode64(Base64.load(obj)) endend

Improve Cookie-based Session with Decorator Pattern 56

Page 57: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Cons• Lack of Flexibility

• Tight coupling

Improve Cookie-based Session with Decorator Pattern 57

Page 58: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Building Coder with Decorator Pattern

Improve Cookie-based Session with Decorator Pattern 58

Page 59: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

class Coder def initialize(coder = nil) @coder = coder end

def encode(obj) raise NotImplementedError end

def decode(obj) raise NotImplementedError endendImprove Cookie-based Session with Decorator Pattern 59

Page 60: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Usageclass JsonCoder < Coder def encode(obj) JSON.dump(@coder.encode(obj)) end

def decode(str) @coder.decode(JSON.parse(str)) endend

Improve Cookie-based Session with Decorator Pattern 60

Page 61: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Usageclass Base64Coder < Coder def encode(obj) Base64.encode64(@coder.encode(obj)) end

def decode(str) @coder.decode(Base64.decode64(str)) endend

Improve Cookie-based Session with Decorator Pattern 61

Page 62: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

A Coder Behaves like Rack::Session::Cookie

coder = HMACCoder.new( Base64Coder.new(MarshalCoder.new), secret: 'secret', digest: 'SHA1')

Improve Cookie-based Session with Decorator Pattern 62

Page 63: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

What about Rails?

Improve Cookie-based Session with Decorator Pattern 63

Page 64: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

A Coder Behaves like RailsCoders::HMAC.new( Coders::Cipher.new( Coders::JSON.new, secret: 'secret' ), secret: 'secret')

Improve Cookie-based Session with Decorator Pattern 64

Page 65: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

gem 'coder_decorator'

Improve Cookie-based Session with Decorator Pattern 65

Page 66: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Demo

Improve Cookie-based Session with Decorator Pattern 66

Page 67: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Can they be part of Rack core?

Improve Cookie-based Session with Decorator Pattern 67

Page 68: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Built-in coders in Rack• Rack::Session::Cookie::Base64::Marshal

• Rack::Session::Cookie::Base64::JSON

• Rack::Session::Cookie::Base64::ZipJSON

• Rack::Session::Cookie::Identity

Improve Cookie-based Session with Decorator Pattern 68

Page 69: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Bad Designs• They are implemented via inheritance

• It repeats itself

• Force to encode in base64 in the end

• The namespace makes no sense

Improve Cookie-based Session with Decorator Pattern 69

Page 70: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Bad Designs• They are implemented via inheritance• It repeats itself

• Force to encode in base64 in the end

• The namespace makes no sense

Improve Cookie-based Session with Decorator Pattern 70

Page 71: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

rack-2.0.4/lib/rack/session/cookie.rbclass Base64 def encode(str); [str].pack('m') end

def decode(str); str.unpack('m').first end

class Marshal < Base64 def encode(str); super(::Marshal.dump(str)) end

def decode(str) return unless str ::Marshal.load(super(str)) rescue nil end endend

Improve Cookie-based Session with Decorator Pattern 71

Page 72: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Bad Designs• They are implemented via inheritance

• It repeats itself• Force to encode in base64 in the end

• The namespace makes no sense

Improve Cookie-based Session with Decorator Pattern 72

Page 73: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

rack-2.0.4/lib/rack/session/cookie.rbclass JSON < Base64 def encode(obj) super(::JSON.dump(obj)) end

def decode(str) return unless str ::JSON.parse(super(str)) rescue nil endend

Improve Cookie-based Session with Decorator Pattern 73

Page 74: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

rack-2.0.4/lib/rack/session/cookie.rbclass ZipJSON < Base64 def encode(obj) super(Zlib::Deflate.deflate(::JSON.dump(obj))) end

def decode(str) return unless str ::JSON.parse(Zlib::Inflate.inflate(super(str))) rescue nil endend

Improve Cookie-based Session with Decorator Pattern 74

Page 75: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Bad Designs• They are implemented via inheritance

• It repeats itself

• Force to encode in base64 in the end

• The namespace makes no sense

Improve Cookie-based Session with Decorator Pattern 75

Page 76: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

rack-2.0.4/lib/rack/session/cookie.rbclass Base64 class Marshal < Base64 end

class JSON < Base64 end

class ZipJSON < Base64 endend

Improve Cookie-based Session with Decorator Pattern 76

Page 77: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Bad Designs• They are implemented via inheritance

• It repeats itself

• Force to encode in base64 in the end

• The namespace makes no sense

Improve Cookie-based Session with Decorator Pattern 77

Page 78: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Built-in coders in Rack• Rack::Session::Cookie::Base64::Marshal

• Rack::Session::Cookie::Base64::JSON

• Rack::Session::Cookie::Base64::ZipJSON

• Rack::Session::Cookie::Identity

Improve Cookie-based Session with Decorator Pattern 78

Page 79: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

A Better Namespace to Put Coders• Rack::Cokers::Coder

• Rack::Cokers::JSON

• Rack::Cokers::Marshal

• Rack::Cokers::HMAC

Improve Cookie-based Session with Decorator Pattern 79

Page 80: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Improve Rack!

Improve Cookie-based Session with Decorator Pattern 80

Page 81: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Difficulty• Backward compatibility

• Signature is not controlled by coder

Improve Cookie-based Session with Decorator Pattern 81

Page 82: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Difficulty• Backward compatibility

• Signature is not controlled by coder

Improve Cookie-based Session with Decorator Pattern 82

Page 83: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Difficulty• Backward compatibility

• Signature is not controlled by coder

Improve Cookie-based Session with Decorator Pattern 83

Page 84: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

rack-2.0.4/lib/rack/session/cookie.rbmodule Rack::Session::Cookie def initialize @secrets = options.values_at(:secret, :old_secret).compact end

def write_session(req, session_id, session, options) if @secrets.first session_data << "--#{generate_hmac(session_data, @secrets.first)}" end endend

Improve Cookie-based Session with Decorator Pattern 84

Page 85: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

https://github.com/rack/rack/pull/1134Improve Cookie-based Session with Decorator Pattern 85

Page 86: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Conclusion• source codes never lie

• mature project can still have some bad design

Improve Cookie-based Session with Decorator Pattern 86

Page 87: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Happy Coding

Improve Cookie-based Session with Decorator Pattern 87

Page 88: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

THANKS FOR YOUR LISTENING@tonytonyjan

Improve Cookie-based Session with Decorator Pattern 88

Page 89: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

References• https://www.wikiwand.com/en/Design_Patterns

• https://github.com/tonytonyjan/coder_decorator/

• https://gist.github.com/tonytonyjan/d71f040fe1085dfcf1d4#file-rails5withpureruby-rb

• https://github.com/rack/rack/pull/1134

• https://github.com/sinatra/sinatra.github.com/pull/220

• https://github.com/rubymonsters/webapps-for-beginners/Improve Cookie-based Session with Decorator Pattern 89

Page 90: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

https://tonytonyjan.net/slides

Improve Cookie-based Session with Decorator Pattern 90

Page 91: Improve Cookie- based Session with Decorator Pattern · @ ConFoo Montreal 2018-03-08 by Jian Weihang Improve Cookie-based Session with Decorator Pattern 1. Bonjour! Improve Cookie-based

Q&AImprove Cookie-based Session with Decorator Pattern 91