Twilio Webhooks in Rails - 401 error - no lines run in method? - ruby-on-rails

I am trying to create a record in a model based on a incoming SMS. This is all in development now. I have the webhooks setup so that the incoming message triggers a webhook which then is processed by the controller. However, the method in the controller doesn't do anything and in the cmd line I get a 401 error.
Here is the code from the webhook controller and the error message:
class TwilioController < ApplicationController
skip_before_action :verify_authenticity_token
def sms_received
#daily_journal = DailyJournal.new
#daily_journal.user_id = current_user.id
#daily_journal.message_sid = params["MessageSid"]
#daily_journal.entry_text = params["Body"]
#daily_journal.save
end
Started POST "/twilio/sms_received" for 54.81.71.35 at 2022-12-04 20:36:57 +0200
Cannot render console from 54.81.71.35! Allowed networks: 127.0.0.0/127.255.255.255, ::1
Processing by TwilioController#sms_received as */*
Parameters: {"ToCountry"=>"US", "ToState"=>"TX", "SmsMessageSid"=>"SMa57a8f9422708b4c3336d33f9be17179", "NumMedia"=>"0", "ToCity"=>"ARLINGTON", "FromZip"=>"22191", "SmsSid"=>"SMa57a8f9422708b4c3336d33f9be17179", "FromState"=>"VA", "SmsStatus"=>"received", "FromCity"=>"ARLINGTON", "Body"=>"R", "FromCountry"=>"US", "To"=>"+18171234567", "MessagingServiceSid"=>"MG4b459339d046009b64e02ad50becab05", "ToZip"=>"76012", "NumSegments"=>"1", "ReferralNumMedia"=>"0", "MessageSid"=>"SMa57a8f9422708b4c3336d33f9be17179", "AccountSid"=>"deleted_but_there_was_something_here", "From"=>"+17031234567", "ApiVersion"=>"2010-04-01"}
Completed 401 Unauthorized in 7ms (Allocations: 690)

Related

401 Unauthorized error when making requests to rails api on heroku

I just deployed my first app to heroku and it used a Rails API (backend) and a React frontend. When I deployed my app I get 401 unauthorized errors whenever I try to make a request that involves the use of a JSON Web Token(JWT). I am sending the token from localstorage in my app and everything worked fine when I was sending it in my development environment. I only have this issue in production.
When I make the fetch request from my frontend and send over my JWT to my backend, I get the following messages in my heroku server logs:
2020-11-29T04:45:31.742735+00:00 app[web.1]: I, [2020-11-29T04:45:31.742670 #4] INFO -- : [f3c19eae-e431-4c9f-b93b-7499797f2c03] [active_model_serializers] Rendered ActiveModel::Serializer::Null with Hash (0.13ms)
2020-11-29T04:45:31.742984+00:00 app[web.1]: I, [2020-11-29T04:45:31.742919 #4] INFO -- : [f3c19eae-e431-4c9f-b93b-7499797f2c03] Filter chain halted as :authorized rendered or redirected
2020-11-29T04:45:31.744091+00:00 app[web.1]: I, [2020-11-29T04:45:31.744019 #4] INFO -- : [f3c19eae-e431-4c9f-b93b-7499797f2c03] Completed 401 Unauthorized in 2ms (Views: 0.7ms | Allocations: 218)
Another strange thing about this is that I get an error message along with the 401 status error in my React frontend that tells me to Please Log in even though I logged into my app to receive a token from my backend before I even attempted to make another fetch request
Below I will post other relevant code snippets so that you can see what I was trying to do
Here is the Code in my frontend that sends the request
addToCart = () =>{
//make a fetch request to add the item in the customer's current cart
fetch("https://health-and-fit-store-api.herokuapp.com/cart_products",{
method:"POST",
headers:{
"Authorization": localStorage.token,
"Content-Type":"application/json",
Accept:"application/json"
},
body:JSON.stringify({
productId :this.props.id
})
})
.then(res => res.json())
.then(data => {
this.props.addToCart(data)
toast.dark(`Added ${data.product.name.toLowerCase()} to your cart`)
})
}
Here is the code in my Rails API that receives the request
before_action :authorized, only: [:create,:delete]
def create
#will be receiving token in fetch request
#use the of the current cart and the product id passed in by the post request
current_cart = #customer.carts.find_by(checked_out:false)
product = Product.find(params[:productId])
new_cart_product = CartProduct.create(cart:current_cart,product:product, quantity:1)
render json: new_cart_product
end
Here is the code from my application controller that I used to set up JWT
class ApplicationController < ActionController::API
def encode_token(payload)
# should store secret in env variable
JWT.encode(payload, ENV['jwt_encode_string'])
#byebug
end
def auth_header
# { Authorization: 'Bearer <token>' }
request.headers['Authorization']
end
def decoded_token
if auth_header
token = auth_header
# header: { 'Authorization': '<token>' }
begin
JWT.decode(token, ENV['jwt_encode_string'], true, algorithm: 'HS256')
rescue JWT::DecodeError
nil
end
end
end
def logged_in_customer
if decoded_token
customer_id = decoded_token[0]['customer_id']
#customer = Customer.find_by(id: customer_id)
end
end
def logged_in?
!!logged_in_customer
end
def authorized
render json: { error_message: 'Please log in' }, status: :unauthorized unless logged_in?
end
end
If anyone can help me out with this, I would really appreciate it, I've been stuck on this for days. Also please note that I have checked out every other post involving this issue on StackOverflow and have exhausted every kind of search on Google that I could think of.
thanks to #snake, I actually ended up solving this issue. The problem wasn't with the token I was using, but their suggestion led me to go back and check out my fetch requests to the api endpoint and I had an extra comma at the end of the request that was causing the 401 status code error.
Once I fixed that, everything worked beautifully.

Rails ActionMailer previews not working

I have a mailer set up within the Rails Tutorial application which works fine.
The previews of the emails was working too when visiting the default path within c9.io: https://app-name.c9users.io/rails/mailers/user_mailer
Previously, this gave me the option to select which outbound email and which format, html or txt, I wanted to view a preview of.
Now, I get a response, as shown, on the page:
And in the logs, I have a 404 with a mention about IP addresses which I don't understand:
Started GET "/rails/mailers/user_mailer" for 88.210.160.9 at 2017-11-15 16:43:20 +0000
Cannot render console from 88.210.160.9! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by Rails::MailersController#preview as HTML
Parameters: {"path"=>"user_mailer"}
Completed 404 Not Found in 252ms (ActiveRecord: 0.0ms)
The log implies I can't access the preview unless I'm local to the server, although this was working fine previously. If I try to access a specific mailer method, I get the same error on the page:
And similar in the trace:
Started GET "/rails/mailers/user_mailer/account_activation" for 88.210.160.9 at 2017-11-15 16:57:41 +0000
Cannot render console from 88.210.160.9! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by Rails::MailersController#preview as HTML
Parameters: {"path"=>"user_mailer/account_activation"}
Completed 404 Not Found in 1ms (ActiveRecord: 0.0ms)
I have views associated with the html & text versions of the emails and a working mailer - this all works as expect, but the previews won't display:
class UserMailer < ApplicationMailer
def account_activation(user)
#user = user
mail to: #user.email, subject: "Account activation"
end
def password_reset(user)
#user = user
mail to: #user.email, subject: "Password reset"
end
end
Any thoughts would be appreciated.
Check if your mailer files bear a .html between their name and their .erb or .slim extension. I had the same issue.

Webhook returning 401 in Rails

I have created a webhook using Fluidsurveys which corresponds to this controller:
class HooksController < ApplicationController
skip_before_filter :verify_authenticity_token
def response_created_callback
# If the body contains the score parameter...
if params[:_completed].present?
# Create a new Response object based on the received parameters...
response = FluidsurveysResponse.new(:completed => params[:_completed])
response.invite_email = params[:_invite_email]
response.locale = params[:_locale]
response.key = params[:_key]
response.webhook = params[:webhook]
response.survey_name = params[:survey_name]
response.username = params[:_username]
response.weighted_score = params[:_weighted_score]
response.completion_time = params[:_completion_time]
response.ip_address = params[:_ip_address]
response.num_responses = params[:num_responses]
response.survey_id = params[:survey_id]
response.invite_name = params[:_invite_name]
response.language = params[:_language]
response.referrer = params[:_referrer]
response.fs_created_at = params[:_created_at]
response.fs_updated_at = params[:_updated_at]
response.survey_url = params[:survey_url]
response.fs_id = params[:_id]
response.collector_id = params[:_collector_id]
response.comment = params[:Comment]
response.nps_score = params[:NPSScore]
response.save!
end
# The webhook doesn't require a response but let's make sure
# we don't send anything
render :nothing => true
end
end
The webhook seems to work fine, as I see this in my logs:
2014-01-20T13:49:01.231772+00:00 app[web.1]: Started POST "/hooks/response_created_callback" for 184.107.171.218 at 2014-01-20 13:49:01 +0000
2014-01-20T13:49:01.327989+00:00 app[web.1]: Processing by HooksController#response_created_callback as */*
2014-01-20T13:49:01.328149+00:00 app[web.1]: Parameters: {"_invite_email"=>"N/A", "_locale"=>"298", "_updated_at"=>"2014-01-20 13:49:00.738850", "_language"=>"en", "_key"=>"b5ec09680a4274cec0052d4049bec338a906e5b8", "webhook"=>"event", "survey_name"=>"Test", "_referrer"=>"http://fluidsurveys.com/surveys/marketing/test-nps-for-dc/", "_username"=>"marketing", "survey_url"=>"http://fluidsurveys.com/surveys/marketing/test-nps-for-dc/", "_id"=>"39164209", "_created_at"=>"2014-01-20 13:49:00.243640", "_weighted_score"=>"0.0", "_completion_time"=>"00:00:00", "_completed"=>"1", "_ip_address"=>"66.192.31.1", "yptmAoJw6i"=>"Detractor: 0", "num_responses"=>"261", "survey_id"=>"263692", "_extra_info"=>"weighted_score", "_invite_name"=>"N/A"}
2014-01-20T13:49:01.369963+00:00 app[web.1]: Completed 401 Unauthorized in 41ms
As you can see, the post gets made to the right controller action. The route is setup correctly, but I get a 401 error. I don't understand what authentication needs to happen here...The params are getting passed to the controller, and in my mind I see no need for my app to authenticate anything. It receives a request, does what it's told, and then it's done.
What am I missing here that is causing the 401 error?
EDIT:
After remove skip_before_filter :verify_authenticity_token from my controller, I get this error:
Can't verify CSRF token authenticity
2014-01-20T16:07:12.222512+00:00 app[web.1]: Completed 422 Unprocessable Entity in 28ms
2014-01-20T16:07:12.225905+00:00 app[web.1]:
2014-01-20T16:07:12.225905+00:00 app[web.1]: ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
The issue is that I am using devise for user authentication, and my app was blocking the post request because there were no authentication credentials being passed to my controller.
By adding this line to my controller I solved the issue:
skip_before_filter :verify_authenticity_token, :authenticate_user!

NoMethodError users_url with devise (ajax)

I use devise 2.2.2 with rails 3.2.11
I use devise with ajax requests
I changed the following configuration in initializers/devise.rb
config.navigational_formats = [:json, :html]
config.http_authenticatable_on_xhr = false
when I submit an empty sign in request, I expect to get a json response with errors hash, but i get a 500 instead (see below for the trace) (it works fine with sign up request)
here are my routes (nothing special)
devise_for :users
the trace:
Started POST "/users/sign_in.json" for 127.0.0.1 at 2013-01-27 13:33:45 +0100
Processing by Devise::SessionsController#create as JSON
Parameters: {"user"=>{"email"=>"", "password"=>"[FILTERED]"}}
Completed 401 Unauthorized in 1ms
Processing by Devise::SessionsController#new as JSON
Parameters: {"user"=>{"email"=>"", "password"=>"[FILTERED]"}}
Completed 500 Internal Server Error in 40ms
NoMethodError (undefined method `users_url' for #<Devise::SessionsController:0x007fe88ddd9550>):
You are probably overriding after_sign_in_path_for and have a code path in there that returns nil.
This causes devise to fall back to its default behaviour and call users_url to get the path to redirect to.
Why do I think this? Because you are having the same error I had (and lost some hair over) and also this bug report contains the github usernames of many other people who have been humbled by this particular issue.

Problem with Rails 3 and AMF , rails3-amf, RocketAMF

im trying to get AMF to work with Rails3.
I have succesfully installed rails3-amf-0.1.0 gem and the RocketAMF-0.2.1 gem.
In my app there is a controller with the following code:
def getRandomCards
#incoming = params[0]
#cards = Cardvo.first
respond_with(#cards) do |format|
format.amf { render :amf => #cards.to_amf}
end
end
through a call from Actionscript i would like to return some data in amf format.
further more, as mentioned in the instructions for rails3-amf i did the following.
in my production.rb under config/environment i added the line
config.rails3amf.map_params :controller => 'CardvosController', :action => 'getRandomCards'
an my amf gateway got
config.rails3amf.gateway_path = "/gateway"
The problem is:
Any call from Actionscript / Flash raises the following
(taken from the log )
Started POST "/gateway" for 192.178.168.1 at Fri Nov 19 15:13:28 +0100 2010
Processing by CardvosController#getRandomCards as AMF
Parameters: {0=>100.0}
[1m[36mSQL (0.4ms)[0m [1mSHOW TABLES[0m
[1m[35mCardvo Load (0.2ms)[0m SELECT `cardvos`.* FROM `cardvos` LIMIT 1
Completed 200 OK in 13ms (Views: 0.9ms | ActiveRecord: 0.5ms)
NoMethodError (undefined method `constructed?' for #<RocketAMF::Envelope:0x39ba868>):
The Amf file is created but the method, which is in remoting.rb from RocketAMF could not be found.
I think the error is thrown at request_parser.rb from Rails3AMF asking for constructed?
# Wrap request and response
env['rack.input'].rewind
env['rails3amf.request'] = RocketAMF::Envelope.new.populate_from_stream(env['rack.input'].read)
env['rails3amf.response'] = RocketAMF::Envelope.new
# Pass up the chain to the request processor, or whatever is layered in between
result = #app.call(env)
# Calculate length and return response
if env['rails3amf.response'].constructed?
For me it seems it is looking at the wron class for the method.
Where
NoMethodError (undefined method `constructed?' for #RocketAMF::Envelope:0x39ba868):
the essential part is
RocketAMF::Envelope:0x39ba868
which should be
RocketAMF:ANOTHER_CLASS:Envelope:0x39ba868
Am i right and where the heck is the error ?
Any help would be appreciated!
chris

Resources