Using attr_encrypted to encrypt and store API token, but how to de-crypt in order to use

3.5k Views Asked by At

Building an app that pulls data from merchant's accounts on demand.

I've setup my model, installed the attr_encrypted gem, and everything is being stored properly as encrypted.

I've created a method that takes the token and sends it to the API, but I need to send the de-crypted version. The token is user specific so I don't know what it is..

How can I send the decrypted version of the token?

In my console I've tried..

x = Merchant.find(1)
x.encrypted_token

And that returns the encrypted version fine..

But if I try:

x.token

The console says ArgumentError: must specify a :key

Which I have stored as an environment variable..

So I guess I pass this along but how??

I have this in my model:

attr_encrypted :token, :key => ENV['token_key']

Updates from comments

this is what my db looks like:

"Merchant(merchant_identifier: string, name: string, encrypted_token: text, 
marketplace: string, password_digest: string, email: string)"

And I tried

    attr_encrypted :token, :key => 'token_key'

and it gave me a cipher error. I'm using figaro to store the environment variables.. seems like that's fine..

Keep it coming!!

What I am doing in irb is:

x = Merchant.find(2)
x.encrypted_token # yields "n4gZVJ8DKfp+p..."

but then if I follow this with

x.token

I get:

ArgumentError: must specify a :key
2

There are 2 best solutions below

0
On

Looks like the key ENV['token_key'] does NOT exist on the env. you are using?

Make sure it does exist and restart that environment and it should work.

5
On

No, you just need to add this to your :attr_encrypted:

attr_encrypted :encrypted_token, :key => Rails.env.test? ? 'ssn_secret' : ENV['SSN_SECRET']

There's also a conditional so that it won't break in production, when you put your keys in a file

Additionally:

By default, the encrypted attribute name is encrypted_#{attribute} (e.g. attr_encrypted :email would create an attribute named encrypted_email). So, if you're storing the encrypted attribute in the database, you need to make sure the encrypted_#{attribute} field exists in your table

So do a Merchant.inspect or Merchant.attribute_names and see what kind of columns you have.