Is there any way to get a Bearer token now, since Robinhood has changed the API again? - api

We keep playing this cat and mouse game with Robinhood.com. I have a trading app which used to trade stocks with Robinhood, but they keep changing the unsupported unofficial API to make it difficult for traders to use. I know that many people are doing the same thing and I want to reach out to them to see if there is a new answer. The latest problem is when I try to get a Bearer token using the URL https://api.robinhood.com/oauth2/token/ the API returns the following JSON: {"detail":"This version of Robinhood is no longer supported. Please update your app or use Robinhood for Web to log in to your account."}. This started happening on 4/26/2019.
Has anyone found a work around for this, yet, or have they finally beaten us into submission?

A more complete solution (not need browser):
Use requests.session.
Obtain the login page by making a GET request to "https://robinhood.com/login".
At this point the session's cookies will contain 'device_id'.
Obtain this device_id and use it in making the oauth2 token request to "https://api.robinhood.com/oauth2/token/" also add in the data request "challenge_type" (either "sms" or "email").
This request will fail with a 400 error code. Robinhood will send an SMS message or Email with a temporary (5 minute) code.
Also at this point use the 400 response's body to get "id" from "challenge" inside of the JSON object.
Confirm the challenge by making a POST request to "https://api.robinhood.com/challenge/CHALLENGEID/respond/" where CHALLENGEID is the same id mentioned in the first failed /oauth2/token/ POST request.
Make the same POST request to "https://api.robinhood.com/oauth2/token/" and include in the header "X-ROBINHOOD-CHALLENGE-RESPONSE-ID" with the value CHALLENGEID.
You can reuse a device_id with user/pass after this even after logging out.
Be cautious with storing device_id as it is the result of user/pass login and successful SMS/email 2FA.

Just got it working. At the risk of them seeing this post and changing it more, here we go:
First, you're going to want to log into your RH account in a web browser
View Source on the page, and look for clientId - it should be a big hex number separated by dashes
Add that number to your POST requests to /oauth2/token under the field device_token
There's probably another way to retrieve the device token, and I'm not even sure it's unique, but that way should work.

Good to be back here after a very long time.
Not sure if anyone is still looking for answers to this, but I have a very simple solution.
At Robinhood's login screen, enter your username/email and your password, press F12 on your keyboard to bring up the console panel and switch to the "Network" tab then wait for the page to load completely. (During this time you will see a list of items being loaded rapidly depending on the connection speed.)
At this time you can keep clearing the list by clicking on the button highlighted in the below image.
Click on button highlighted repeatedly until the list is empty
Now, log into your Robinhood account. At this point your console should display a list similar to the one shown below.
Look for the name "token/", most likely it will be the second one you get all the information you need. And this information will be under the Headers then Request Payload
I was able to find this with past knowledge and experience of web scraping for fun. And also, I needed to know this as well, since I recently started doing trades via Robinhood.
Hope this help you curious ones out there.

For my Robinhood account I am using Google Authenticator for my 2FA. What I have so far is that I send the original call that I was sending before to https://api.robinhood.com/oauth2/token/. This is giving me a response of:
{"mfa_required":true,"mfa_type":"app"}
I then repeat my oauth token request, but this time providing the value from Google Authenticator (so my GUI has to prompt me to fill it in) with this payload in the request to https://api.robinhood.com/oauth2/token/:
{"grant_type":"password","scope":"internal","client_id":"c82SH0WZOsabOXGP2sxqcj34FxkvfnWRZBKlBjFS","expires_in":86400,"device_token":"***","username":"***","password":"****","mfa_code":"***"}
and then I am getting an access token in reply

Related

Implementing OAuth2 with Socrata API

I'm implementing the Socrata API to be able to parse publicly-available data from the City of Chicago open data set. I am really just concerned about the data itself, so I did not initially think that I would need to implement OAuth2 through an app exposed via ngrok to be able to GET the data.
My initial attempt was to take the GET requests mentioned in their documentation and try to get responses through Postman.
Here's an example of such an attempt:
I also added my Socrata App Token as a param in the querystring, but the same message was shown.
So I tell myself, ok, maybe they deprecated GET requests without making the client go through OAuth2. If they didn't deprecate these GET requests, I would prefer not to have to deal with OAuth2, but I began implementing the authentication process and everything went successfully until I got to the following instructions found here:
I have every single value that needs to be included in that POST request except for 'authorization_type'. Where does this come from? I tried leaving 'authorization_type' in as a string, but received a response similar to the 'Invalid username or password' message in the top image in this question.
Are you only accessing public datasets from Chicago's data portal? From your screenshot it looks like you're trying to access the Building Permits dataset, which is public.
Authentication is only required for modifying datasets or accessing private data, so chances are very good you don't even need to authenticate. Just include an application token with your request for throttling purposes.
Glad to help you figure out your OAuth workflow, but it sounds like it might be unnecessary.

detecting link checkers (spam filter) in incoming HTTP requests

We have a site that uses a "one-time" login process for password resets which are not initiated by the user themselves. (for instance, a password reset that is initiated by an admin or another employee) A URL is sent to the user via email which can then be used to reset their password. The URL can only be visited one time. (there's more to this for security-sake but I'll keep it simple) Recently, some users have complained that when they visit the link, it has already expired. The end result is that they can't reset their passwords using this feature. We discovered that the users in question have a spam filter or "link checker" in their environment that they do not have access to. This device visits the one-time link before the user is able to, to make sure its safe.
I'm trying to solve this issue and was wondering if there's a way I can detect these type of devices on the web server when the request is made? When the spam filter visits the link, is there something in the http request that would stand apart from a regular browser? Maybe they all use a specific custom HTTP header? Or maybe there's a regex I could use on the user agent? I haven't been able to catch one of these yet, so I'm not sure what the request looks like coming from a spam filter.
Anyone know of a way to detect spam filters of any vendor by looking at the http requests? I know it's a long shot but maybe they all use a specific header for reasons such as this?
I got approval to modify the design to remove the one-time aspect of the URL. This solves the issue and saves me the headache. Thanks for the suggestion, #PeeHaa

Authenticating QuickBooks API

I don't believe I need OAuth
Then again, what do I know
All I want to do is take someone's credit card information and charge them. I am not accessing other people's QuickBooks accounts (only my own) and I am not trying to access any other personal information other than what they input into my form. For this reason it seems absolutely asinine to think that I'd have to redirect them to intuit.com and force them through an OAuth prompt (what account would they even be authorizing? They probably don't have a QuickBooks account)
I've spent the last hour reading through QuickBook's API documentation and I've run in circles and found the whole thing utterly confusing. Every page which references a particular API endpoint makes no mention of authentication -- only the headers, query parameters, and request body that are expected. The API explorer does not show any form of authentication in their examples:
No basic auth header, nothing in the request body with an API token,.. nothing
Checking the console while hitting submit isn't any more helpful. The request gets sent to their back-end server where it does the real request:
It even includes "apikey", "apisecret", and "oauth" attributes in the body which are all empty -- it acts like the endpoint doesn't even NEED authentication.
Out of dumb curiosity I tried making the request with no authentication to see what would happen:
401 Not Authorized. So some authentication is needed. I continued to scour the docs and turned up nothing but page after page linking me back to OAuth and saying that I need to set up OAuth. Why do I need to set up OAuth to take a credit card number that was given to me and hand it to QuickBooks?
I even tried looking at their sample app. The "take the code for a test drive" (https://developer.intuit.com/v2/ui#/emulator?workflow=ecommerce) was utterly worthless. It only gave me some pseudo-code with zero idea for how to handle authentication:
I even looked at the actual code and don't see anywhere that they provide an API key or secret key.
I'm pretty much ripping my hair out at this point, so I think I need someone with experience to point me in the right direction.
I don't believe I need OAuth
You do.
For this reason it seems absolutely asinine to think that I'd have to redirect them to intuit.com and force them through an OAuth prompt
You misunderstand what OAuth is, and how it's used.
OAuth is used to get YOUR auth tokens so that YOUR COMPANY can authenticate to Intuit and identify itself so you can charge customer credit cards. YOU are redirected to Intuit's website to authenticate ONCE, and ONCE ONLY, and then NEVER AGAIN.
You store the tokens you get back from the one-time OAuth pop-up window process, and use those for all future HTTPS requests.
The end-user (i.e. your customer) is NOT redirected.
If you're familiar/used to something like Authorize.net or other web services, where you open a web browser and go to a website and copy a secret key/API token into your code... this is the exact same process except instead of you logging in and manually copy/pasting an API token/key, you're logging in and the OAuth process automatically gives you the API token/key programatically.

Can you send sub-sequential HTTP POST request to a sever

I'm just getting started in HTTP POST requests. So much so that I've got no idea if this is even going to solve my problem, but it seems like an interesting thing to learn about either way. Anyway, I currently do the following with a webbrowser control:
Navigate to a page
Enter username and password
Click the 'login' button
Enter some text into textboxes
Click another button (which loads a confirm page)
Click the confirm button
My question is does the HTTP POST request thing allow for the webclient to stay logged into the webpage, does it allow for posting to the page and then posting again once the update page has been received (steps 4, 5 and 6).
So you want to scrape some web content or manipulate a site from a program or script, but you're having a hard time. No, just switching to a POST will not help you here. Often, the problem has to do with authentication. What you need to do is preserve your session across more than one HTTP request, whether the requests are POST, GET, HEAD, DELETE, PUT, UPDATE, etc.
As mentioned in a comment, HTTP requests are stateless, where each request is independent of the others. However, web servers will still maintain some information for individual sessions, and so you usually still need more than one request. However, I find that much of the time, exactly two requests are enough to accomplish an action on a web site.
The first request will POST your login information to the site. At this point, the web site will issue a response. You need to analyze this response, because somewhere in there will be a session key. Now when I tell you to analyze the response, I don't mean that you write code to do this... that will come later. You need to actually send a sample request record the response, and read through it with your own eyes to find the session key. You also need to know how the web server expects to find the session key on future requests.
In this process, it's important to remember that a response consists of more than just HTML. In fact, the most common location for this key is in a cookie. Once you know how to get the session key, you need to make sure your next request includes that session key as part of the request. This is how the web site will know who you are, that you are authorized to perform the desired action, and what information to return.
The second request will actually perform the desired action. This could be a simple GET request, if all you want to do is retrieve some information from the site. It may also be POST, if you need to tell the site to perform some action.
To know what your requests need to look like, you can use a special kind of http proxy. Fiddler is a popular choice. You install the proxy to your computer, and then perform the desired action from a regular web browser. Fiddler will then tell you what requests and responses were sent. Even if you need to view a number of pages to complete your action via your web browser, often you still only need the final request to actually accomplish your goal. You use the information provided by fiddler to find and duplicate the required requests.
In the .Net world, the best tool for sending these requests and evaluating the responses is generally not the WebBrowser control. Instead, take a look at the System.Net.WebClient class, or look at System.Net.HttpWebRequest/System.Net.HttpWebResponse.

IOS Authentication with DB online

I have to build an App that need authentication over a DB (online).
When application load, at first appear a login screen to insert user credentials.
Thus after a correct login, user can access every areas of this app.
I think to use this steps, what do you think about?
1) Build a PHP (or other lang) Webservice that accept username/password(crypt) and check this data. When user is found, create a token with some strange unique string and adding a expiration time information. Send token back as response with some sort of json structure.
2) The IOS APP call this service passing username/password, if the webservice response is positive, store the received token in NSUserdefault and add time of creation (so i can calculate when it expire.
3) From my APP i can make request toward webservice sending my token. WS checks Token validity and send back a response.
Is this a good practice ???
Yes and no.
I think your approach will work as you wrote it. But keep in mind, that your users needs an internet connection to use your app. So I would design the structure in a way it has also a use for the user, if he has no internet connection.
I also don't know how good your expirience is with Webservices and the communication with them. If you send the data, you should also encrypt the sent data, because they are the credentials of the user. So it's not save to send them as GET Values for examples in a PHP script...
I hope my answer did help a little bit. If you have specific questions on this type of webservice, just ask. I did this a few times before. ;-)
Sandro Meier