How to pass access token in context for particular mutation in apollo graphql client - apollo

I am integrating the Microsoft graph API in my application, so currently I am getting access token at the client-side through MSAL npm module, so I need access token at the apollo server to hit the Microsoft graph API's(This access token is only required for only one resolver, for the application authorization I have different access token that I check for every resolver), so is there any way I can add context while mutation like I tried this -
<Mutation mutation={CREATE_MICROSOFT_TEAMS} context={{ microsoftgraphaccesstoken: msalAccessToken }}> I have tried to pass context in the mutation but it doesn't work, is there something like this, or should I pass the token in the argument and then add that in to the headers when my apollo server is going to hit the microsoft graph API's.

There are multiple ways to access the token server-side, the easiest way is to consider the token as part of the mutation variables, since it is specific to one resolver anyway.
Using mutation variables:
// client.js
<Mutation
mutation={CREATE_MICROSOFT_TEAMS}
variables={{ microsoftgraphaccesstoken: msalAccessToken }}
>
// server.js
function createMsTeamsResolver(source, args, context, info) {
console.log(args.microsoftgraphaccesstoken);
}
That way you can also access any arguments as you would normally.

Related

Django REST framework - prevent data access for user view?

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

Reactjs app making requests to Django which exists on different domain

I'm trying to make a request from my reactjs app existing on "localhost:3000" to my django living in "localhost:8000"
I was expecting some authentication token in header to passed along with the request, but it's not the case. The request seems to be stripped and the token is nowhere to be found. Unless I pass the token in the url as a parameter (which exposes the token that can be decoded. I don't like it), I can't seem to be able to get the token in any way.
so my questions:
is this CORS issue? My understanding is that CORS usually deals with javascripts only, and Django already has the middleware to deal with this.
I'm currently using a GET as method. Does using a POST help in this case? How would the reactjs script be written? Currently it's just a href attached to a NavItem
and ultimately:
How do I pass the token from reactjs to django?
We can perform the implicit grant on the front-end and then configure the Django API in Auth0 and specify its identifier in the audience parameter. This would grant you an access token which you could then use against your API. Your API would then verify the token and check the audience is correct. (This has a good overview of the process https://auth0.com/docs/api-auth/grant/implicit and then with the API https://auth0.com/docs/architecture-scenarios/spa-api)
Basically what we can do is when Auth0 authenticates the user it redirects the user to the app with an access token, and optionally an id token, in the hash fragment of the URI. We can extract that and use the token to call the API on behalf of the user.
So, after we have [created the API in Auth0][3, [defined the endpoints]3, and secured the endpoints we can call the API (by sending the access token in an Authorization header using the Bearer scheme).
If you have any Auth0 specific question please feel free to join over in community.auth0.com you may have better luck finding help/solutions.
The 403 error is telling you that the request is not being processed because something is stopping from process that request 403: The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated
As you said probably because the CORS, try to follow the guide bellow of how to install Django-cors
https://github.com/mbrochh/django-graphql-apollo-react-demo#add-jwt-authentication-to-django

make custom API call with authentication

I am trying to develop an application that should eventually replace an existing (non-Ember) one and provide additional functionality.
For a start, for anything not yet implemented in the new app, I want to redirect users to the existing one, using the latter's single-sign-on capability. The workflow I imagined is this:
User logged in to new (Ember) app clicks link or button there
New app makes an API call to an endpoint that returns an SSO token
New app generated link including SSO token, opens it (in new or same window)
I use ember-simple-auth to authenticate the user for API calls that return user-specific information, using a JSON web token that contains the user id.
For step 2 above I would need to include that token in the API call, but I am at loss how, and even where to implement the call. Do I need an Ember.Route for this (where I could throw in the AuthenticatedRouteMixin)? I would not consider the SSO token to be part of my model, so that does not seem right. Can I get the session's token somehow and include it in a direct ajax call? Should I?
ember-simple-auth provides the SessionService where you can access that information.
My recommendation is to use ember-ajax to make the actual request, and override the ajax service to call the session services authorize method.
Then you need to implement your authorizer to authorize that request.
The detail implementation depends on your authorizer and how you want to include the token in your request. As header, query param, or in the body.

Initializing FB session on client using javascript sdk and long lived token

I am a bit confused about the implementation of access token in FB graph api.
According to the docs I can pass the access token to client and initialize the session using this access token
https://developers.facebook.com/docs/facebook-login/access-tokens
So if I have a long lived access token on server side and pass it to the javascript sdk on client side...is it possible to make graph api calls from client? How?
Facebooks's JS SDK .api() method always accepts a parameter called access_token, that can be a User access_token or a Page access_token depending on the calls you are making. See the following example using Angular's SDK:
Get a
this.fb.api(pageId + '?fields=picture,fan_count,name', 'get', { 'access_token': <USER_ACCESS_TOKEN> })
Where <USER_ACCESS_TOKEN> is given to you by your backend without exposing your API secret ever. So, in summary.
See Generating Long-Lived User Tokens from Server-Side Long-Lived Tokens for more info.

Emberjs and Simple Auth for any $.ajax

I am doing an $.ajax post command and i currently have an authenticated session on the client side. I am trying to figure out how to add the token to the ajax call (as on the server i check the token to see if it matches in my local database. How is it possible to use that same auth token in a generic ajax call ?
Thanks
You add the token as a request header in your authorizer.
To do this, either use one of the including solutions (if you're using the corresponding backend), or implement your own custom authorizer.
If you have to write your own, you can look at the devise authorizer's authorize method for an example of how to add the header.