Rails API 422 Unprocessable Entity: No verification key available, heroku - ruby-on-rails

I created a Rails API with a JWT authentication system and deployed it to Heroku. When I request the endpoints locally, all seems to be working fine but when I make requests to the live endpoints (i.e the Heroku deployed app) I get a: 422 Unprocessable Entity server error and the response body looks like this:
{
"message": "No verification key available"
}
The class responsible for encoding and decoding the auth token is defined as follows:
class JsonWebToken
# secret to encode and decode token
HMAC_SECRET = Rails.application.secrets.secret_key_base
def self.encode(payload, exp = 24.hours.from_now)
# set expiry to 24 hours from the creation time.
payload[:exp] = exp.to_i
# sign token with application secret
JWT.encode(payload, HMAC_SECRET)
end
def self.decode(token)
# get payload, first index in decoded Array
body = JWT.decode(token, HMAC_SECRET)[0]
HashWithIndifferentAccess.new body
# rescue from all decode errors
rescue JWT::DecodeError => e
# raise custom error to be handled by custom handler
raise ExceptionHandler::InvalidToken, e.message
end
end
I have an endpoint /signup where I can make a POST request to register a new user and POST /todos which is accessible and available only to registered users. Making a registration request works perfectly fine, but when I try to make the POST request to the /todos endpoint it raises an error.
The association between user and suit is 1:m respectively.
Please if you have any idea on how I can fix this, I'll be very grateful, thanks : ).

I finally figured a way out by altering the Rails.application.secrets.secret_key_base to Rails.application.secret_key_base. For a more detailed review on this please check out this link. Hopefully, this will help someone facing a similar issue.

This was also my problem. After checking out my json_web_token.rb file, I figured out that I had written the following line:
HMAC_SECRET = Rails.application.secrets.secret_key_base
There is an extra secrets reference, which is causing the problem. It should be:
HMAC_SECRET = Rails.application.secret_key_base
But as far as I'm concerned, you managed to figure it out yourself!

Related

RoR / RSpec request cookie change not persisting when changed in test case

I'm trying to test that refreshing a user session works (using JWT web tokens). The server passes back an access cookie to be used for web and after hitting the refresh endpoint I am trying to set the request cookie to be the response cookie, and then making another request to validate that the new access cookie is valid.
The issue that I am facing is that despite setting the request cookie to the response cookie before making the next request it still uses the old request cookie (which is expired).
This is the test case:
it 'maintains a users session' do
JWTSessions.access_exp_time = 0
external_sign_in(identifier: user.mobile_number, password: 'password', client: :web)
JWTSessions.access_exp_time = 3600
puts request.cookies[JWTSessions.access_cookie]
post :refresh
request.cookies[JWTSessions.access_cookie] = response.cookies['jwt_access']
request.headers[JWTSessions.csrf_header] = response_json['csrf']
puts '======='
puts response.cookies['jwt_access']
puts request.cookies[JWTSessions.access_cookie]
puts '======='
get :index
puts request.cookies[JWTSessions.access_cookie]
expect(response_json['message']).to include(user.first_name)
end
Context: externa_sign_in is a helper method that sets the correct csrf header and request cookie when the client is :web.
Output from the put statements:
eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjY3NTk5MzgsInVzZXJfaWQiOjIxNjYsInVpZCI6Ijc3NmIwYTIyLWI3ZWUtNDhmYy1hYWIzLWM5MTMyZGQ2ZDAyZiIsImV4cCI6MTU2Njc1OTkzOCwicnVpZCI6IjkzM2RmMTZjLWYwZjYtNDlmYy1hYWZhLTk5MmE2NjhmMTk3YyJ9.SWPGjSKzJVbCr7cBTFiAZieLOfgLnNWTjKfY2w3LTZc
=======
eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjY3NjM1MzgsImV4cCI6MTU2Njc2MzUzOCwidXNlcl9pZCI6MjE2NiwidWlkIjoiNzAwNTdhODQtN2MzNC00M2M2LWE4MzYtZjI0ODIxNTdlM2Y2IiwicnVpZCI6IjkzM2RmMTZjLWYwZjYtNDlmYy1hYWZhLTk5MmE2NjhmMTk3YyJ9.0lkiJ9Iu3R3NHSg0RsGzoSh2rVhwGnp5X0ZYS2jvncQ
eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjY3NjM1MzgsImV4cCI6MTU2Njc2MzUzOCwidXNlcl9pZCI6MjE2NiwidWlkIjoiNzAwNTdhODQtN2MzNC00M2M2LWE4MzYtZjI0ODIxNTdlM2Y2IiwicnVpZCI6IjkzM2RmMTZjLWYwZjYtNDlmYy1hYWZhLTk5MmE2NjhmMTk3YyJ9.0lkiJ9Iu3R3NHSg0RsGzoSh2rVhwGnp5X0ZYS2jvncQ
=======
eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjY3NTk5MzgsInVzZXJfaWQiOjIxNjYsInVpZCI6Ijc3NmIwYTIyLWI3ZWUtNDhmYy1hYWIzLWM5MTMyZGQ2ZDAyZiIsImV4cCI6MTU2Njc1OTkzOCwicnVpZCI6IjkzM2RmMTZjLWYwZjYtNDlmYy1hYWZhLTk5MmE2NjhmMTk3YyJ9.SWPGjSKzJVbCr7cBTFiAZieLOfgLnNWTjKfY2w3LTZc
Also it seems like the csrf header updates, so not sure what's going on.
In order to do this you need to do cookies.delete(...) before setting the cookie again. Not sure why, but it seems to fix it.

Undefined method `OAuth' when making HTTP request to Twitter api

I'm getting the following OAuth error when trying to make a request to the Twitter streaming api:
"#NoMethodError: undefined method `OAuth' for #TwitterMoment:0x007fa081d821f0"
def query
authorisation_header = OAuth oauth_consumer_key=ENV["oauth_consumer_key"], oauth_nonce=ENV["oauth_nonce"], oauth_signature=ENV["oauth_signature"], oauth_signature_method=ENV["oauth_signature_method"], oauth_timestamp=ENV["oauth_timestamp"], oauth_token=ENV["oauth_token"], oauth_version=ENV["oauth_version"]
response = HTTParty.get("https://stream.twitter.com/1.1/statuses/filter.json?locations=-#{#bounds}", headers: {"Authorization" => authorisation_header})
end
OAuth is included in my gemfile.
Any ideas would be very much appreciated! This is my first Stack Overflow question :)
You're using OAuth here as a function/method, but that method doesn't exist. There's no def OAuth(...) anywhere in the oauth gem, so it explodes and gives you that NoMethodError.
Judging from the Header example at the bottom of this question, I think you've confused the header string for Ruby code.
Instead, you either need to make the string yourself (a bit annoying to do safely), or use the OAuth gem's methods (API) to do so.
Here's an example from the OAuth github repo:
consumer = OAuth::Consumer.new(
options[:consumer_key],
options[:consumer_secret],
:site => "http://query.yahooapis.com"
)
access_token = OAuth::AccessToken.new(consumer)
response = access_token.request(
:get,
"/v1/yql?q=#{OAuth::Helper.escape(query)}&format=json"
)
rsp = JSON.parse(response.body)
pp rsp
This example may work for you (I'm not able to test it locally here, sorry):
def query
consumer = OAuth::Consumer.new(
ENV["oauth_consumer_key"],
ENV["oauth_consumer_token"],
site: "https://stream.twitter.com"
)
access_token = OAuth::AccessToken.new(consumer)
response = access_token.request(
:get,
"/1.1/statuses/filter.json?locations=-#{OAuth::Helper.escape(#bounds)}"
)
response = JSON.parse(response.body)
pp response # Just a bit of debug printing for the moment; remove this later.
response
end
An addendum:
Usually I might have directed you to use an existing Twitter client gem, such as https://github.com/sferik/twitter, but in this case it looks like they haven't implemented the Moments API yet.

Handling ENV Variables in api request

I am making a request to the facebook graph api and have saved my USER_ID and ACCESS_TOKEN in ENV variables. I'm wondering if this is a best practice as this morning I am encountering a URI error that I was not getting yesterday.
class FacebookFeed
#Constants
VANDALS_ID = ENV['VANDALS_FB_ID']
FB_ACCESS_TOKEN = ENV['FACEBOOK_ACCESS_TOKEN']
FACEBOOK_URL = 'https://graph.facebook.com/"#{VANDALS_ID}"/posts/?access_token="#{FB_ACCESS_TOKEN}"'
def get_feed
uri = URI(FACEBOOK_URL)
response = HTTParty.get(uri)
results = JSON.parse(response.body)['data']
puts results
end
end
So in the Rails console I am just trying to get a response but am getting:
URI::InvalidURIError: bad URI(is not URI?): https://graph.facebook.com/"#{VANDALS_ID}"/posts/?access_token="#{FB_ACCESS_TOKEN}"
This is strange as this was working yesterday. Is there anything I am missing or is there a better way to store my User_ID and Access Token?
Update
When doing a 'puts uri' this is returned:
https://graph.facebook.com/%22%23%7BVANDALS_ID%7D%22/posts/?access_token=%22%23%7BFB_ACCESS_TOKEN%7D%22
I assume this is what is being sent as the GET request, because when I then do 'puts response' I get:
{"error":{"message":"Invalid OAuth access token.","type":"OAuthException","code":190}}
How do I construct the request correctly?
After talking to Rich on Skype, the problem was resolved with Sergey Kishenin's comment:
FACEBOOK_URL = "https://graph.facebook.com/#{VANDALS_ID}/posts/?access_token=#{FB_ACCESS_TOKEN}"

Handle oauth errors with Google Ruby Client?

I'm using Google API Ruby Client (gem 'google-api-client') in a Rails Web app, and I'd like to know how to catch specific errors in the oauth flow. In particular, what should I look for in the rescue statement? Here's the function called by the redirect after the user authorizes:
require 'google/api_client'
def google_auth_finish
begin
client = Google::APIClient.new
client.authorization.client_id = GOOGLE_CLIENT_ID
client.authorization.client_secret = GOOGLE_CLIENT_SECRET
...
rescue ## WHAT GOES HERE TO IDENTIFY THE ERROR?
# Handle the error
logger.info "There was an error."
end
end
Is there a reference somewhere with defined errors? I've searched and can't find it.
I know this was asked years ago, but I literally just encountered this problem and happened upon this question. You were just missing a small part. This worked for me. I am still relatively new, but in my case it prevented the program from breaking and printed out the error message, then the program continued on.
rescue Exception => error
puts "Error #{error}"
end
try theseRaising An Exception

Rails: OAuth2 gem returns 400 error when attempting to connect to facebook

I'm attempting to add Facebook connect to our web app, and I'm running into a problem with. Everything works fine locally (I can authenticate through Facebook), but when I push the code to our dev server (which lives in the wild), every time I try to authenticate it returns the following error code:
OAuth2::HTTPError: Received HTTP 400 during request
That's really the only explanation I'm getting. Again, this works on my local machine, and the gems and such match between boxes, so I'm a bit confused. Here's the code I'm executing.
def facebook_connect
#Set the scope we want to pull from Facebook, along with the callback URL
options = {
:redirect_uri => facebook_callback_url,
:scope => "email,publish_stream"
}
#Go out and fetch the url
client = OAuth2::Client.new(FACEBOOK_API_KEY, FACEBOOK_SECRET, {:site => FACEBOOK_API_URL, :access_token_method => :post})
#Redirect to the callback for processing
redirect_to client.web_server.authorize_url(options)
end
def facebook_callback
#Client URL
client = OAuth2::Client.new(FACEBOOK_API_KEY, FACEBOOK_SECRET, {:site => FACEBOOK_API_URL, :access_token_method => :post})
#Parse out the access token
access_token = client.web_server.get_access_token(params[:code], :redirect_uri => facebook_callback_url)
#Get the user
fb_user = JSON.parse(access_token.get('/me'))
#Do some authentication database stuff
end
def facebook_callback_url
uri = URI.parse(request.url)
uri.path = '/users/facebook_callback'
uri.query = nil
uri.to_s
end
I searched Google, but the solutions that show up aren't working. Also, if anyone knows how to parse and display OAuth2 errors, I would appreciate that, as well. Thanks
Assuming that Facebook OATH knows of your server's IP address(they are very strict about it), I would recommend that you use use 'rescue' to catch that exception, get the backtrace and then find where it is being raised and place a bunch of debug statements to check the state of both request and the response, as well as access tokens.
Or you can configure remote debugging with Rubymine or NetBeans which is not an easy task :)
The issue actually ended up being a problem with the "Faraday" gem. Our dev server wasn't set up to handle SSL, which was returning an error code. We patched it using the following answer:
OmniAuth & Facebook: certificate verify failed

Resources