I have a unique issue in Scala Play. I noticed that when we have multiple pages, suddenly the sessionId changes when traversing through the pages, one page in particular (this happens only in QA though) and the server is not able to retrieve correct data from the database. I am asked to troubleshoot it. Any tips on where to look? The sessionID is retrieved from either the HeaderCarrier, if not present, then the request itself.
Any documentation on how this class HeaderCarrier interacts with the server request will be much helpful.
Related
For facebook Conversion API to work I need to generate a unique event_id that is the same on browser and server, so that facebook can deduplicate it.
More on this here: https://developers.facebook.com/docs/marketing-api/conversions-api/deduplicate-pixel-and-server-events
Now my problem is, that sometimes the server fires an event first, sometimes the client.
So generating IDs on client first or on server first is tricky to do (at least, I would have to refactor quite a lot).
Is there any other way to reliably build unique IDs on browser and server without them communicating to each other?
Background:
I have a single page application that pulls data from a REST API. The API is designed such that the only URL necessary is the API root, ie https://example.com/api which provides URLs for other resources so that the client doesn't need to have any knowledge of how they are constructed.
API Design
The API has three main classes of data:
Module: Top level container
Category: A sub-container in a specific module
Resource: An item in a category
SPA Design
The app consuming the API has views for listing modules, viewing a particular module's details, and viewing a particular resource. The way the app works is it keeps all loaded data in a store. This store is persistent until the page is closed/refreshed.
The Problem:
My question is, if the user has navigated to a resource's detail view (example.com/resources/1/) and then they refresh the page, how do I load that particular resource without knowing its URL for the API?
Potential Solutions:
Hardcode URLs
Hardcoding the URLs would be fairly straightforward since I control both the API and the client, but I would really prefer to stick to a self describing API where the client doesn't need to know about the URLs.
Recursive Fetch
I could fetch the data recursively. For example, if the user requests a Resource with a particular ID, I could perform the following steps.
Fetch all the modules.
For each module, fetch its categories
Find the category that contains the requested resource and fetch the requested resource's details.
My concern with this is that I would be making a lot of unnecessary requests. If we have 100 modules but the user is only ever going to view 1 of them, we still make 100 requests to get the categories in each module.
Descriptive URLs
If I nested URLs like example.com/modules/123/categories/456/resources/789/, then I could do 3 simple lookups since I could avoid searching through the received data. The issue with this approach is that the URLs quickly become unwieldy, especially if I also wanted to include a slug for each resource. However, since this approach allows me to avoid hardcoding URLs and avoid making unnecessary network requests, it is currently my preferred option.
Notes:
I control both the client application and the API, so I can make changes in either place.
I am open to redesigning the API if necessary
Any ideas for how to address this issue would by greatly appreciated.
Expanding on my comment in an answer.
I think this is a very common problem and one I've struggled with myself. I don't think Nicholas Shanks's answer truly solves this.
This section in particular I take some issues with:
The user reloading example.com/resources/1/ is simply re-affirming the current application state, and the client does not need to do any API traversal to get back here.
Your client application should know the current URL, but that URL is saved on the client machine (in RAM, or disk cache, or a history file, etc.)
The implication I take from this, is that urls on your application are only valid for the life-time of the history file or disk cache, and cannot be shared with other users.
If that is good enough for your use-case, then this is probably the simplest, but I feel that there's a lot of cases where this is not true. The most obvious one indeed being the ability to share urls from the frontend-application.
To solve this, I would sum the issue up as:
You need to be able to statelessly map a url from a frontend to an API
The simplest, but incorrect way might simply be to map a API url such as:
http://api.example.org/resources/1
Directly to url such as:
http://frontend.example.org/resources/1
The issue I have with this, is that there's an implication that /resource/1 is taken from the frontend url and just added on to the api url. This is not something we're supposed to do, because it means we can't really evolve this api. If the server decides to link to a different server for example, the urls break.
Another option is that you generate uris such as:
http://frontend.example.org/http://api.example.org/resources/1
http://frontend.example.org/?uri=http://api.example.org/resources/1
I personally don't think this is too crazy. It does mean that the frontend needs to be able to load that uri and figure out what 'view' to load for the backend uri.
A third possibility is that you add another api that can:
Generate short strings that the frontend can use as unique ids (http://frontend.example.org/[short-string])
This api would return some document to the frontend that informs what view to load and what the (last known) API uri was.
None of these ideas sound super great to me. I want a better solution to this problem, but these are things I came up with as I was contemplating this.
Super curious if there's better ideas out there!
The current URL that the user is viewing, and the steps it took to get to the current place, are both application state (in the HATEOAS sense).
The user reloading example.com/resources/1/ is simply re-affirming the current application state, and the client does not need to do any API traversal to get back here.
Your client application should know the current URL, but that URL is saved on the client machine (in RAM, or disk cache, or a history file, etc.)
The starting point of the API is (well, can be) compiled-in to your client. Commpiled-in URLs are what couple the client to the server, not URLs that the user has visited during use of the client, including the current URL.
Your question, "For example, if the user requests a Resource with a particular ID", indicates that you have not grasped the decoupling that HATEOAS provides.
The user NEVER asks for a resource with such-and-such an ID. The user can click a link to get a query form, and then the server provides a form that generates requests to /collection/{id}. (In HTML, this is only possible for query strings, not path components, but other hypermedia formats don't have this limitation).
When the user submits the form with the ID number in the field, the client can build the request URL from the data supplied by the server+user.
I'm developing a service, that uses social graph.
There is a separate module, that manages user connections, that is basically responsible for all related operations. In some services, you need to know all user connections, to provide correct responses.
The way I see it there are 4 possible options to implement this:
Server based connection support.
1.1. Each time social graph data requested ask for friend list from the module, and process corresponding response.
1.2. Have internal cache with Key - playerID, Value - all player connections, add responsibility to update this cache to connection module, and use it instead of referring to this module.
Client based connection support.
2.1. Add a special Cookie with the list of all friends, so that server could just read that Cookie and provide needed information, without talking to the external module. (This can be secured, by for example providing some signature for the Cookie, and optimised by adding some path, for all the connections related data)
2.2. Add a connection management layer in Client, so it would explicitly request all needed information, by providing a list of connections on each request.
As I look at facebook Cookies, there is a fr cookie, which I can speculate used for this kind of functionality.
How facebook solves this?
If you just want to maintain a list of friends for each user you don't need a full social graph. A simple list of friends stored in your database would work fine.
Client-side storage is typically only for caching or session data, you don't want your users losing their friend list because they re-installed their browser or switched computers.
If you do want to implement a full social graph have a look for a graph DB. Neo4J is one I've used and is fairly easy to get started on.
I'm getting familiar with Breeze because I think that it can help me a lot dealing with data. Hovewer my biggest concern is data validation on server side. I read the documentation and I know that you should use your own ContextProvider and apply custom validation inside. I also read this SO post where someone was asking similar question.
But I think I got the case that cannot be handled in BeforeSaveEntity function. If it can, please tell me how:
Let's say that user is trying to update an article (his own article). This article has some ID.
How could I check if user is updating his article and not someone elses (he could change article ID in the browser, and this ID could be someone elses article ID). So entity would be still valid, but business rule does not allow to change other users articles by everyone.
I want to use EntityFramework and ASP.NET Web Api by the way.
If only i could get to something like "current user" and ID of article inside BeforeSaveEntity function...
You are rightly concerned to validate client save requests thoroughly and right also to distrust-in-principle anything the client sends.
Two issues here: who is the user and does s/he really own this article.
Who is the user?
Breeze stays out of the authentication business which we believe should be addressed by means that are (largely) external to the application code you write on server and client.
I would not roll my own security layer. That's asking for trouble. You might start your research with this article by Mike Wasson on Web API security.
Once you know who the user is, you must get application-specific facts about him or her such as the userId and what the user is allowed to do. I don't know where you get those facts as that is something specific to your application.
Whose article is this?
Let's suppose the current userId is 12345 and the update request specifies an article with articleId == 42 and userId == 12345. Clearly this article belongs to the current user. Is that good enough? Should we go ahead and save the changed article?
The answer depends upon how you assess the consequences of a rogue client updating another person's article. I'm not worried about updating a Todo (maybe I should?). I wouldn't trust this request if it concerned a bank withdraw.
I recommend spinning up a separate DbContext and querying the database for articleId 42.
Do not query the database with the DbContext from the Breeze ContextProvider inside the BeforeSave. That DbContext holds the modified article from the client. You want a separate DbContext to hold the actual entity per the database as it stands right now. These are separate entity objects in separate states. You can't have two different articles with the same id in the same DbContext.
If the queried article has userId 12345, you know the client made a valid request and you proceed. If the queried article's userId property is other than 12345, you reject the request.
You might treat this failed request as a potential attack and log it where you log security attacks. Maybe you'll monitor this user and the IP address and who knows what. I'm out of my depth here.
I'd probably reject the request with a mysterious 500. A real client wouldn't have made such a request and I don't want to tell a potential attacker the reason I rejected it.
All,
I need to create an app for work that signs into our website using SSL and returns our member information.
I have figured out how to log in but am not sure how to find the id tags that I want to bring into my app and store to be show in a table view.
I know how to do these three things.
Put in username and password,
authenticate against website,
create session cookie.
Not sure how to do these things.
Get information about member, ie, how long a member , sustaining member, ect from the website knowing the tags for these fields on the site.
Store the data (core data?) or flat file. Shouldn't be that much information.
Format and present data in table view.
Lots of information here about getting files or whole websites but not so much about picking information off websites for concise viewing.
Thanks.
If your company's site is designed to provide this information through a web service, then it should be as simple as constructing your request URLs appropriately. If it has not been designed to interact with anything but humans, then you're probably going to have to do a great deal of work parsing HTML which no one can really help you with unless said site is publicly accessible.
Web Services should work fine with our website.