Edit: This is a mostly Rails question
I'm trying to implement instant payment notification API (IPN), which calls your server if the Paypal payment goes through. The problem I'm seeing now is when Paypal IPN hits the url I designated, it is failing with the following error:
> Started POST "/checkout/complete?id=1&amount=3445&authenticity_token=NkOwgJ1H2TEmwO6T+hROu96kWr4yGcTzHD6MbTswgyU="
> ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
The authenticity_token it uses is the one I passed during the initial phase while redirecting to Paypal. Apparently, that's not a valid option. When I leave that blank, though, it's throwing the same error.
I wonder if I can disable authenticity_token requirement or get around it somehow, so that when Paypal posts to my app it can go through without any errors.
Sounds like the csrf is causing the issue, adding skip_before_filter :verify_authenticity_token to your controller should allow it to process.
If your using that authenticity_token as a security measure, then store and check it manually in your controllers.
Related
I have a Rails 5 app and am using a form to submit data. I am using CSRF protection and the form generates a hidden field 'authenticity_token'. Works great!
But sometimes a user gets and error 'Can't verify CSRF token authenticity'. And I am wondering why this happens? I can only imagine that the user has cookies disabled. But which normal internet user does that? Are there any other reasons?
I am not able to reproduce this error on my computer. So the only solution I have is to disable CSRF protection which is not really what I would like to do.
Any ideas?
Can't verify CSRF token authenticity results in 500 Internal Server.
I am wondering why this happens? I can only imagine that the user has cookies disabled. But which normal internet user does that? Are there any other reasons?
Yes, this happens. Or maybe the user(or hacker) tries to make an API request to the endpoint and since, it can't verify the authenticity token it will throw this error. A normal user doesn't do this, but maybe someone who values their privacy and may turn these settings off, or maybe they want to use Tor browser and so on. As developers, all we can do is try to provide best possible experience to the end user.
So, A better practice is to catch 500 Internal Server error with some custom message and then display it to the end user, while also sending the Stack trace to yourself(slack notification etc.) so that you can work on if it's a critical issue.
This way, If everything is good from user's end, this will work normally. But If someone disables cookies(or anything that results in some error), you can display custom message about the issue.
I have been trying to validate that when the silent post comes into my application it is validated that it is indeed from Paypal. I have tried both in the following link.
PayPal Payments Advanced -- Validate Parameters Sent to Confirm and Cancel Pages
Neither seems to work. When i try to pass a token it just does not send. If I do it manually it works but it seems the regular params sent with Paypal "override it".
I tried using NVP/SOAP and Rest API and neither of them work either.
I JUST need a simple way that will WORK to know that the silent post I am receiving is Paypal and a valid transaction 100%. A secure token would seem to work great but no cigar so far.
Application is in Ruby on Rails.
If this is still not working for you, you might want to check on the URL from which you receive the silent post
URL: notify.paypal.com (Payflow Silent Post)
IP address: 173.0.81.65
Here is a pro module documentation from broadleafcommerce.com
http://www.broadleafcommerce.com/docs/paypal-payflowpro/current/paypal-payflow-pro-environment-setup
Found something similar here
How do you verify that the notification to the Silent Post URL is indeed from PayPal Payflow and not a hacker?
I'm using Devise for authentication in a Rails 4.2 app. Most of the users are not having any issues logging in and getting their work done, but there is one user in particular that appears to consistently have a bad CSRF token and can't log in.
Of course, the following is what's logged:
W, [2015-02-17T20:58:19.261194 #1936] WARN -- : Can't verify CSRF token authenticity
I, [2015-02-17T20:58:19.263556 #1936] INFO -- : Completed 422 Unprocessable Entity in 5ms
F, [2015-02-17T20:58:19.276795 #1936] FATAL -- :
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
<stack trace>
Perusing the logs shows me that the user's CSRF token changes as you'd expect, but it is consistently (100% of the time) rejected by the server.
Originally, I thought this was an issue with that user's browser. I started logging the user agent when logins are attempted and asked that user to try with several browsers; she has, and all are able to reproduce the same issue.
I reset her password and was able to log into the account using new credentials. She still cannot log in.
She has dumped her cache and cleared cookies several times. Likewise, a runthrough with anti-malware software returns no results (this is probably the most suspect).
What am I missing? Is there something I need to do on the server side in order to fix this issue, or is it likely an issue with her computer itself?
The issue has been resolved, at least temporarily. After some searching through issues on the Devise issue tracker, I happened across this snippet (for placement in config/initializers/session_store.rb) that seemed to help:
Rails.application.config.session_store :cookie_store, key: "_rails_session_#{Rails.env}", domain: :all
The user is not having any problems signing in at this point. I suspect it was either that the user was not properly clearing her cookies or that there was a mixup somewhere in the code. At any rate, it seems to be fixed.
I'm having an issue integrating PayPal into my Rails 3 app using Ryan Bates's screencasts as a guide ( http://railscasts.com/episodes/143-paypal-security).
After payment's complete on the PayPal sandbox, the user's redirected back to the correct URL. Everything from encryption to IPN works great.
For some reason, though, Rails throws a routing error immediately when the user's redirected from PayPal--even though the resource exists. The page repeats the error when I refresh the page, but when I navigate to the URL on my own it renders correctly. The routing error only occurs when PayPal redirects to my app.
I'm using Rails 3.0.10 with Ruby 1.9.2.
Has anyone ever seen this before? What's the cause?
Thanks!
If I remember correctly, the production version of PayPal does a POST of the redirect URL, while the sandox would do a GET. Which is, I know, weird!
Can you change your route for the specific redirect action to match instead of get and try again!?
Also, make sure you exempt it from protect_from_forgery :)
I am using the ruby twitter gem and oauth to gain access to users twitter accounts. In my code, I have:
unless #user.twitter_authd?
oauth = Twitter::OAuth.new('token', 'secret')
session[:twitter_request_token] = oauth.request_token.token
session[:twitter_request_secret] = oauth.request_token.secret
#twitter_auth_url = oauth.request_token.authorize_url
end
where token and secret have my actual token and secret inserted. When I click on the link to the #twitter_auth_url, I am taken to twitter and asked to grant access. I click allow and then twitter redirects me to my callback URL http://www.mydomain.com/twitter_callback/?oauth_token=fmy2aMvnjVgaFrz37bJ4JuB8r5xN79gsgDQRG4BNY which then hits this code:
oauth = Twitter::OAuth.new('token', 'secret')
logger.info("session[:twitter_request_token] = #{session[:twitter_request_token]}")
logger.info("session[:twitter_request_secret] = #{session[:twitter_request_secret]}")
oauth.authorize_from_request(session[:twitter_request_token], session[:twitter_request_secret])
session[:twitter_request_token] = nil
session[:twitter_request_secret] = nil
#user.update_attributes({
:twitter_token => oauth.access_token.token,
:twitter_secret => oauth.access_token.secret,
})
redirect_to root_path
The twitter request token and secret are being set just fine. However I end up with an authorization error:
OAuth::Unauthorized in MainController#twitter_callback
401 Unauthorized
RAILS_ROOT: /Users/TAmoyal/Desktop/RoR_Projects/mls
Application Trace | Framework Trace | Full Trace
/Library/Ruby/Gems/1.8/gems/oauth-0.3.4/lib/oauth/consumer.rb:167:in `token_request'
/Library/Ruby/Gems/1.8/gems/oauth-0.3.4/lib/oauth/tokens/request_token.rb:14:in `get_access_token'
/Library/Ruby/Gems/1.8/gems/erwaller-twitter-0.6.13.1/lib/twitter/oauth.rb:29:in `authorize_from_request'
/Users/TAmoyal/Desktop/RoR_Projects/mls/app/controllers/main_controller.rb:70:in `twitter_callback'
The code is failing at this line:
oauth.authorize_from_request(session[:twitter_request_token], session[:twitter_request_secret])
when it tries to get an access token. You can see the source code of authorize_from_request here. I am not sure why this is happening. Anyone have ideas?
A bit late to the party but just ran into the same issue myself. I tracked the issue down to the setup of my OAuth app in Twitter. I had initially not specified a callback URL as I was unsure of it.
Once I had setup my rails app I went back to find Twitter had assumed I was a desktop application as I hadn't specified a callback URL. Once I changed this to website and entered a callback URL I stopped getting 400s.
If you're getting error 401 - OAuth::Unauthorized, make sure you edit the settings of your Twitter application as follows:
Application Type: Browser
Callback URL: http://127.0.0.1:3000/auth/twitter/callback
this is an issue about time synchronization of your system with twitter server.
Twitter doesn't allow localhost as part of a valid callback URL.
Instead use http://127.0.0.1:3000/auth/twitter/callback
Hope this helps
This was one of the most annoying things to debug that I have come across. I was outputting in a couple places by accident because the URL's are dynamic and they happened to not be defined in my test case (i use this to display chart data and there is not enough right now so the google chart api URL's are blank). This caused my browser to make multiple requests to my localhost when some pages were loaded. Somehow that made the oauth process crap out. Obviously there is no way for people on S.O. to know about my application specific issue so I had to answer my own question.
I had this same problem and none of the suggestions in this thread worked for me.
I found the problem for me was the TIMESTAMP on my request. The mobile device I was running my scripts on had a jacked up clock. When I updated the system time on my device to the correct time (i.e. now), all of my requests came back "200 OK" instead of "401 Unauthorized".
This problem seems to be caused by twitter not being able to handle connection keep-alive correctly. Make sure you set connection=close http header in the request to twitter. Wasted a weekend debugging this.
not enough info for me, but when was twitter gem last updated? twitter changed their oauth 'stuff' in mid may approx. perhaps you have an old one. I'd update your question to show the callback_url, and make sure you have the right token and secret, which it looks like you don't have.
also, did you put the right callback url in your twitter app page? alot of times that screws you up too.
if that fails use mbleighs twitter_auth instead. it worked for me and is pretty slick.