My app loads a list/connection on startup and I'm using FB login. For auth with Relay I'm setting a cookie but the cookie is removed in case the app is removed from running in the background.
To avoid that the user has to login again I'm caching (AsyncStorage) the user info, if the user exists in there I'm auto login the user at the server so I get my Cookie back. The problem is that I need to reset/reload the connection, I tried a mutation with Field_Change returning the parent (which should include all it's children but it doesn't load the connection which is a child of a child).
I also tried to reset/recreate the store, also without success.
The list is loaded on my start page so I'm not changing pages.
My connection does have multiple params for paging as well as others and an #include.
The only way I could get it to work is to use forceUpdate in the component that also defines the connection, is there a better way?
Update:
Here's the fat query:
fragment on AuthorizationChangePayload #relay(pattern: true) {
viewer {
user
}
}
And the config for the mutation:
return [{
type: 'FIELDS_CHANGE',
fieldIDs: {
viewer: this.props.viewer.id
}
}];
Within user there's the connection which doesn't get updated, I didn't specify it as it has parameters and really I want to update the whole user and it's children objects.
Related
In my application i’m getting the users IP address and then timezone on the server in getserversideprops in order to display user specific content and keep the SEO benefits of server side rendering.
On every page of the site my serversideprops looks like:
// check if timezone cookie exists
// if not, get ip and timezone
// set timezone cookie
// use cookie to retrieve user specific data and return in props
It works fine but it doesn’t feel right writing duplicate code like that and having it on every page.
Is there a way to set/retrieve the cookies in _app.js or something similar to context but for the server?
In my api, I have a /users endpoint which currently shows (eg address) details of all users currently registered. This needs to be accessed by the (Ember) application (eg to view a user shipping address) but for obvious reasons I can't allow anyone to be able to view the data (whether that be via the browsable api or as plain JSON if we restrict a view to just use the JSONRenderer). I don't think I can use authentication and permissions, since the application needs to log a user in from the front end app (I am using token based authentication) in the first instance. If I use authentication on the user view in Django for instance, I am unable to login from Ember.
Am I missing something?
UPDATE
Hi, I wanted to come back on this.
For authentication on the Ember side I'm using Ember Simple Auth and token based authentication in Django. All is working fine - I can log into the Ember app, and have access to the token.
What I need to be able to do is to access the user; for this I followed the code sample here https://github.com/simplabs/ember-simple-auth/blob/master/guides/managing-current-user.md
I have tested the token based authentication in Postman, using the token for my logged in user - and can access the /users endpoint. (This is returning all users - what I want is for only the user for whom I have the token to be returned but that's for later!).
The question is how to do I pass the (token) header in any Ember requests, eg
this.store.findAll('user') .... etc
This is clearly not happening currently, and I'm not sure how to fix this.
UPDATE
Fixed it. Turns out that the authorize function in my application adapter was not setting the headers, so have changed the code to set the headers explicitly:
authorize(xhr) {
let { access_token } = this.get('session.data.authenticated');
if (isPresent(access_token)) {
xhr.setRequestHeader('Authorization', `Token ${access_token}`);
}
},
headers: computed('session.data.authenticated.token', function () {
const headers = {};
if (this.session.isAuthenticated) {
headers['Authorization'] = `Token ${this.session.data.authenticated.token}`
}
return headers;
})
Ember is framework for creating SPAs. These run in the browser. So for Ember to get the data, you have to send the data to the browser.
The browser is completely under the control of the user. The browser is software that works for them, not for the owner of the website.
Any data you send to the browser, the user can access. Full stop.
If you want to limit which bits of the data the user can read from the API, then you need to write the logic to apply those limits server-side and not depend on the client-side Ember code to filter out the bits you don't want the user to see.
I don't think I can use authentication and permissions, since the application needs to log a user in from the front end app (I am using token based authentication) in the first instance. If I use authentication on the user view in Django for instance, I am unable to login from Ember.
This doesn't really make sense.
Generally, this should happen:
The user enters some credentials into the Ember app
The ember app sends them to an authentication endpoint on the server
The server returns a token
The ember app stores the token
The ember app sends the token when it makes the request for data from the API
The server uses the token to determine which data to send back from the API
When i try to called:
Auth::getInstance()->authenticate($email,$password)
for authenticate in login controller, i called Auth::getInstance()->isAuthenticated() and get result bool(true). Then i go redirect to another page, Auth::getInstance()->isAuthenticated() give bool(false). After i use this authentication, how can i get the session is already bool(true) at any page after that until i'm Auth::getInstance()->unauthenticate() that session or make it global for the session? Currently i'm using session database.
Problem : How to authenticate the current user after redirect to another page?
Without knowing more about your code, I can predict a couple of possible sources of this type of behavior...
1) You're not writing the fact that the user is authenticated to your session/cookie, so the second page request isn't aware of the result of the first one.
2) If the authentication is successful on the first page (and you record this in the session/cookie), and the redirection happens, but you redirect back to a page already seen by the user (e.g. Homepage -> Login page -> Homepage) then your browser might be loading it out of it's local cache rather than fetching the new (authenticated) page from the server.
Try dumping your session variables to the browser to see if the authentication result is being preserved between requests, and try appending a timestamp on the redirection url or using headers to prevent client side caching. This will at least allow you to narrow down, or eliminate these two options.
The Auth plugin already manages all session control for authentication without any additional effort from the developer.
The problem you are facing could likely be because the session is not starting for some reason. This could be because Nuclio isn't detecting that it is being run from a browser. Nuclio detects this by checking REMOTE_HOST and HTTP_HOST values in $_SERVER. If both are null, it won't start the session (to avoid generating headers on a command line).
Also make sure that your base application class is extending the Nuclio Application plugin class and NOT overriding the __construct method without calling the parent construct method as this would cause all the initialization to fail and no session will be created/resumed.
The page to login to our application is a jsp hosted on another machine. I have managed to get requests firing to this machine by modifying authenticated-route-mixin by allowing window.location.replace to be called if the route start with http.
beforeModel(transition) {
if (!this.get('session.isAuthenticated')) {
Ember.assert('The route configured as Configuration.authenticationRoute cannot implement the AuthenticatedRouteMixin mixin as that leads to an infinite transitioning loop!', this.get('routeName') !== Configuration.authenticationRoute);
transition.abort();
this.set('session.attemptedTransition', transition);
debugger;
if (Configuration.authenticationRoute.startsWith('http')) {
window.location.replace(Configuration.authenticationRoute);
} else {
this.transitionTo(Configuration.authenticationRoute);
}
} else {
return this._super(...arguments);
}
}
This is working but when I am redirected back to my application, ember-simple-auth thinks I am no longer logged in and redirects be back to the remote machine, which then sends me back to the application in an infinite loop.
Obviously I need to set something to let ember-simple-auth know that it it is actually logged in. Why is it not doing this automatically? What am I doing wrong?
I am pretty new to oAuth so I could be missing some basic setting here.
Here is the URL.
ENV['ember-simple-auth'] = {
authenticationRoute: 'https://our-server.com/opensso/oauth2/authorize?client_id=test-client-1&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A4200%2Fsecure'
};
Instead of modifying the AuthenticatedRouteMixin, I'd recommend handling your app-specific login in an Authenticator-- the key configuration primitive that Ember Simple Auth provides as part of its public API.
To the best of my understanding, on first loading the app, and checking to see if a user is authenticated, Ember Simple Auth will use the restore method, defined as part of the Authenticator API.
You can return a promise from restore that resolves or rejects to indicate whether the user is authenticated. How you check this is an implementation detail of your auth system.
I don't know how you're storing credential(s) on the client (would be great if you could provide more detail), but here's an example flow, using cookies for authentication:
Ember boots, ESA attempts to restore the session.
restore makes a simple AJAX request to a secured, "dummy" resource on your Java server-- and checks if it gets back a 200 or a 401.
We get a 401 back. The user isn't authenticated, so reject in the Promise returned from restore.
Let ESA redirect the user to your authentication route. Ideally, don't override the AuthenticatedRouteMixin-- instead, use the beforeModel hook in the authentication route to send users to your JSP login page.
The user correctly authenticates against the JSP form.
In its response, your Java server sets some kind of encrypted, signed session cookie (this is how it generally works with Rails) as a credential. In addition, it sends a redirect back to your Ember app.
Ember boots again, ESA calls restore again.
restore pings your Java server again, gets a 200 back (thanks to the cookie), and thus resolves its Promise.
ESA learns that the user's authenticated, and redirects to the 'route after authentication'.
Keep in mind that, at its core, ESA can only indicate to the client whether the backend considers it 'authenticated' or not. ESA can never be used to deny access to a resource-- only to show something different on the client, based on the last thing it heard from the backend.
Let me know if any of that was helpful.
I have an Ember application that requires user authentication on the server side. Once authenticated (via login), application runs normally. The application shows a logout button. Pressing this logout button sends a message to the server, which causes the server to terminate the session, does some clean up, and sends the login page for the client to display. All this works fine.
But here's the problem: if the user hits the browser's 'back' button after logging off, he will see the app again and can interact with it. The app can still send messages to the server. Currently, the server will always respond by sending back the login page when the session is already terminated. How do I get ember to transition to this login page received from the server? The fact that users can still get back to a running application (at least on the client side) after logging off would cause some confusion.
What's the recommended method for handling this? Is there anyway to make the Ember application end when the user hits the logout button? Maybe just disable the browser's back button when the user logs off (how do you do this in Ember?)?
You can either check in every route if the session is loggedIn or not in activate hook of route like this..
if you are setting a variable loggedIn true here is how to do it.
App.PostRoute = Ember.Route.extend({
activate: function() {
if (!loggedIn){
this.tansitionTo('login');
}
}
});
If you want to remove totally PostRoute from history you can use replaceWith rather transitionTo.
.or use these for authentication ember-auth or simple-auth