Shopify landing_site Order Attribute - shopify

I have a client that is asking for pretty detailed information about how the landing_site attribute of an Order resource works. The documentation here says that this is set to the first page that someone visits when they come to the shop.
How persistent is this? For example, if someone visits a shop (entering via the home page, let's say) then I assume that the landing_site will be "/". Let' say that visitor then comes back a day or two later (this time via a link with a ref parameter) and visits a product page. Does the landing_site attribute update to "/products/sample-product?ref=mytoken"?
If not, how long does this value persist? Is there a way to reset it? If someone at Shopify could explain this, I think it would be something that a lot of app developers would reference.
Thanks.

Session
If the customer never creates a cart, then cookies are used to keep a reference to this data. curl -I snowdevil.myshopify.com can be used to see how persistent these cookies are:
Set-Cookie: _session_id=...; path=/; HttpOnly
This header value shows that a session cookies is being stored, which means it will expire when the user closes their browser. It also indicates that only a session_id is stored, so the session data itself is stored on the server.
The data will not be stored indefinitely on the server, because there isn't a way to know when the user closes his browser. Currently, the session data itself will expire after 1 day.
Cart
This same value will also get persisted along with any cart data when a product is added to the user's cart. So, if you look at your cookies for you shop just after adding a product to your cart, you will see there is a separate "cart" cookie which currently expires after 2 weeks. This data will persist this long, even after the user has closed their browser, but will not persist if the user deletes their cookies.
Disclaimer
A key word to take note of here is "currently", since to my knowledge, Shopify has not made a commitment to keep this data around for a certain amount of time.

Related

How to get client specific session data in a callback_url that has no access to the client

I have a callback_url that, by all accounts, lives in a vacuum. A third-party (Shopify) hits the URL, and with very strict constraints at that.
I have tried these but I cannot:
add params to the URL
control the headers/payload
utilize existing cookies (this isn't the user hitting the callback)
Really, I can't find anyway to get session data, or more specifically, a very crucial customer Id, to the callback_url. The callback_url is being used to send back user-specific data but that's not possible without some key indicator (customer ID)
Am I missing something simple or is this as much of a challenge as I thought? I feel like it's on an island.

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

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

Any way to generate a Auto Login/Token Authentication Link?

I have an account that I do referrals on and instead of having to make an entire landing page, and provide users with my referral link - I'll just have them purchase from my account.
Is there any way I could generate a link that will automatically log users in without me having to reveal my password?
You could definitely do this by using something like a JSON Web Token (JWT).
Basically, the way it works is like this:
On your server, you create a JWT that is signed with a secret key (some random string that only your server knows).
In your JWT, you include your user's account ID that you want the purchase to come from.
You email this JWT to the person in a link, something like https://mywebsite.com/order?token=<jwt-token-here>.
The user clicks that link.
Your web server takes the token out of the URL parameters, and ensures it is valid (that the signature is good).
Your web server then finds the account ID in the token, and retrieves that user account from your user database.
You then LOG that user in using cookies or whatever, and direct them to the purchase page fully logged in!
This is a pretty typical web flow for what you're trying to do, and is a totally fine way to do things like this. There are tons of JWT libraries out there that make this easy to do, so it shouldn't be very technically challenging.
The only other thing you should know in regards to creating JWTs, is that you can set an 'expiration' time. You should DEFINITELY do this, as you don't want someone to be able to log in using your token months in the future. The best way to do it would to likely be generate a token that lasts for 24 hours or so, then email THAT to the user. This way, it expires after one day.
Last thing to know: there are actually quite a few auth libraries that simplify this stuff. I'm the author of one, myself: express-stormpath. Depending on what you're trying to do, that might actually make your life wayyy easier as it can generate those tokens automatically, and handle session creations for ya.
Hope that helps!

Coldfusion 'thank you' page allows user to refresh unlimited times

Hi guys I need some advice please.
Our payment gateway sends back some data when an order is succesfully posted that is included in the url string.
The only problem is users are refreshing the page and sending through a bunch of cfmail commands each time they refresh the thank you page!
Which is better for our security, to setup a redirect to our home page shortly after this page is loaded, to setup a way to stop the user loading the page more than once or to strip out the order info so the user can't click refresh?
Below is a sample url that the payment gateway generates upon a succesful transaction.
http://www.ourwebsitename.com/ConfirmationPage.cfm?cartinfo=^XXXX^1&orderinfo=Customer^Name^Billing Name^Billing^Line^1^Town^Postcode^websitename^Order^Amount^&responsesitesecurity=SECUREHASHCODE&thisorderid=OURORDERID
What are people thoughts on securing this page?
The way I've addressed this in the past is to do the following
On any page that the user is shown, try not to have any of the logic that actually does anything. Display logic only on display pages
At the end of the checkout process, send the email, and then use <cflocation> to redirect to the confirmation page
Add some check-bit to the session or whatever you use to keep track of the user to flag that the email has already been sent
If you REALLY don't want users resending the email twice, use a <cflock> and confirm that the flag mentioned in #3 hasn't been flagged inside the <cflock> (to make sure it hasn't been sent by the process that locked it)
This should help reduce / remove the impact of the user refreshing. When I've had this in the past it's been due to people placing logic on the output pages that should really have been on one of the pages that the user doesn't get shown (due to them silently redirecting)
I suggest that you add a confirmation_email_sent-column to your order table in the database, and then set this flag the first time you send the email. If the users refreshes the page, you will notice that this flag is already set, and can then skip sending the email. If there are other side effects than the e-mail-sending, then these should probably be mitigated in the same way.

Preserving authentication cookies, but disallowing concurrent access at different sites

I have a web application where I want users to only be able to use it from one location (meaning a user can't actively be using the application at two locations). Currently I got this working in a very common way by only allowing 1 cookie session to be valid and removing any existing ones when a user logs in. Unfortunately I've been told that my method of only allowing 1 cookie is unacceptable because my users move around a lot to different sites and are tired of having to login every time. An easy solution would just be to allow more than 1 cookie, but I can't do this because I need to make sure a user account is not being used at two locations at the same time.
I'm wondering what is the best way to implement a system like this where a user can't be active at more than 1 location, but shouldn't necessarily have to login at every location they visit.
One possible idea I had was to allow multiple cookies to be recorded, but once a cookie becomes active (meaning I notice that session navigating the application) all of the other cookies are locked out for a certain timelimit like 15 mins. If no cookie session has been active for 15 mins then allow any cookie to login and gain dominance over the others untill it exceeds the timelimit.
Edit: It's ok for them to remain logged in after they leave a location
One way to do this is to log their last ip address and at what time that access was. On each access, you can check their last access.
If the last access is from the same ip, let them through.
If the last access is from a different ip, check how long ago that was. You can then define a cut-off point for how long they need to be idle before they can access it from another location. 15 minutes seems reasonable.
All of this can be done on the backend and this would possibly provide a higher level of security.
The browser allows users to store their credentials. Let them use this feature to log back in without hassle.
No need for a timeout. Allow multiple cookies, but only one active one.
Instruct your users to close the application when they leave their workstations. Make this something that's easy to do. Put a close button on each page or perhaps catch onBeforeUnload and notify the server that the page is no longer being displayed. Do keep the session when the user closes the application, but mark it as currently inactive.
When you get a request with a cookie that belongs to an inactive session, activate that session without complaints if the user has no other session active.
If the user still has another session active, something fishy is going on. So remove all sessions and send the user to the login screen.
(That'll teach them :) )