fireproofsocks
I’m working on an Elixir implementation of Shopify’s Multipass feature – it’s basically a single-sign-on (SSO) flow that lets your app handle authentication, and on success, it produces a URL that when clicked will cause a customer record to be upserted into Shopify. They include working examples of how to do this in PHP and Ruby, but I cannot make it work in Elixir.
You have to enable the feature and they give you a 32 character shared secret key.
# Example key from Shopify Admin
multipass_secret = "1234567890abcdef1234567890abcdef"
customer_data = %{
email: "test@test.shopify.com",
created_at: DateTime.to_iso8601(Timex.now()), # <-- the token will only be valid for a small timeframe around this timestamp.
}
key_material = :crypto.hash(:sha256, multipass_secret)
# Split the key into 2 binaries each containing exactly 16 bytes
<< encryption_key::binary-size(16), signature_key::binary-size(16) >> = key_material
customer_data_as_string = Jason.encode!(customer_data)
# Initialization Vector
ivec = :crypto.strong_rand_bytes(16)
to_add = 16 - rem(byte_size(customer_data_as_string), 16)
padded = customer_data_as_string <> :binary.copy(<<to_add>>, to_add)
cipher_text = ivec <> :crypto.block_encrypt(:aes_cbc128, encryption_key, ivec, padded)
signature = :crypto.hmac(:sha256, signature_key, cipher_text)
message = cipher_text <> signature
token = Base.encode16(message, case: :lower)
"https://yourstore.myshopify.com/account/login/multipass/#{token}"
Note that this feature is only available in Shopify Plus accounts.
Links I’ve been pouring over:
- crypto — OTP 29.0.2 (crypto 5.9)
- https://stackoverflow.com/questions/37629194/how-to-encrypt-and-decrypt-with-aes-cbc-128-in-elixir
Does anyone have some pointers on converting this? Thanks!
Trending in Questions
Hello!
Suppose you are building workflow (order / task / payment) processing system with the following requirements:
Each workflow con...
New
I’m aware of 2 such projects, are there others?
git: GitHub - team-alembic/realworld: A fullstack Phoenix LiveView application with back...
New
Hi all,
I’m working on a Phoenix project where I need to make external HTTP requests and I’m trying to choose between Req and HTTPoison....
New
How do I tell Hologram not to escape HTML when substituting into templates?
{Textile.render(@product.long_description)}
escapes the HTM...
New
I’d like to create a file with 600 permissions (rw-------), but there’s a race condition if I create it and then change the permissions. ...
New
Hi,
we run different LLM models across a cluster, with each node loading a configurable subset. Model-specific queues let nodes consume ...
New
When I use Mix.install with a git dependency, using git@github.com:... how do I change the SSH identity used?
I’ve got two Github accoun...
New
Other Trending Topics
Hey there,
I haven’t seen a list of useful Elixir specific skills for the popular AI tools yet so I’m starting one here with my first.
...
New
Hi everyone :waving_hand:
I wanted to share something I’ve been building — NowBlind, a random chat app designed to help people discover ...
New
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
(I just needed to vent somewhere and LinkedIn is full of hope, or hype, I’m not sure which exactly)
AI dream has many faces, but general...
New
Localize is the next generation localisation library for Elixir. Think of it as ex_cldr version 3.0. The first version will be released ...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #code-sync
- #discussion
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #ai
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #blog-post
- #elixirconf-us
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #elixirconf-eu
- #processes
- #security
- #api
- #forms
- #performance










Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
Ninigi
Do you get a meaningful error? What exactly happens when you try this?
fireproofsocks
No error on generation, but when I click the link to head over to Shopify, I get a bad request error. Using the PHP or Ruby code samples results in a working link that logs me into the Shopify store.
Ninigi
Before diving too deep into this, can you try
EDIT
I took the provided ruby code on the Shopify documentation, replaced dynamic values with static values (the json string and
iv) and used the resulting token to set up a simple test.I think you already had it:
Just change
Base.encode16/2toBase.url_encode64/1fireproofsocks
WOW. That has to be the best typo I’ve made in weeks! Base 16?!? I was so focused on the hard parts of the crypto stuff that I didn’t pay attention to the last bit. THANK YOU!!
fireproofsocks
For the record, here is the complete working proof-of-concept code:
maz
It’s so easy to mess-up crypto.
NobbZ
Yeah. That might be the reason behind the first rule of the crypto club:
Ninigi
Good to hear you solved it
If you have some spare time, a pull request to implement multipass would be more than welcome!
fireproofsocks
Sure – the process does require that customer data be JSON encoded. Can you recommend how to nicely implement that as a dependency? Or should I restructure the input to make the user do the JSON encoding outside of your package?
Ninigi
the package already uses Poison for json processing, so I think you should not have to introduce a new dependency