I'm trying to integrate getstream.io into our framework to deliver activities to subscribers and also allow clients to filter activities. GetStream doesn't allow filter on activities, So I had to create new group and link the activities through to property. Is this the proper way to do filter?
We need to allow clients to update the activity with bookmarks/comments from browser. I'm having issue here.
var activity = {
actor: 'org_1:user_1',
verb: 'start',
object: 'site',
time: '2018-04-18T11:19:04.263000',
foreign_id: 'site_id:1',
comment: 'start properly'
}
client.updateActivities([activity]).then(
function(res) {
console.log('res:',res)
},
function(err) {
console.log('err:',err)
}
);
The code gives following error in browser but works when executed from the node.js server
getstream.js:2107 Uncaught TypeError: jwt.sign is not a function
at Object.exports.JWTScopeToken (getstream.js:2107)
at StreamClient.updateActivities (getstream.js:816)
at <anonymous>:8:8
I pass the feed token that is generated in the node.js server to client to make connection to the feed group.
Should I add JWT to the updateActivities request, If so what should the payload contain and how do I add a token to the request?
True. JWT is only included as a back-end dependency and not compiled in your front-end assets, probably.
Updating activities is not an operation to be done on the front-end side of your application. The only recommended operation on the front-end is getting more activities with a read-only token and client.feed(...).getActivities().
Cheers
Related
Is there a way to pass dynamic data to the Stripe API? I'm using the example found here: https://stripe.com/docs/payments/checkout/client
I'd like to be able to pass a token along with the purchase in order to link an account with that payment. After the client side sends the payment to the API, my backend would receive the details of the payment, including the token to link it to an account created before this. I would add it as a param to to the successful redirect, but if they close the window early then the accounts will not be linked. I set up my product using the dashboard.
I tried using metadata and description as a part of the line item, but it keeps saying "Invalid stripe.redirectToCheckout parameter: lineItems.0.description is not an accepted parameter."
let token;
stripe.redirectToCheckout({
lineItems: [{
price: 'boop', // Replace with the ID of your price
quantity: 1,
description: token
}],
mode: 'payment',
successUrl: 'http://boop.com',
cancelUrl: 'http://boop.com',
}).then(function (result) {
// If `redirectToCheckout` fails due to a browser or network
// error, display the localized error message to your customer
// using `result.error.message`.
});
Thank you!
In order to pass metadata and other fields in Checkout, you need to use the Server + Client integration path instead of the client-only integration.
You can achieve what I wanted through the Server + Client integration by using the client_reference_id when creating a session.
Hi I'm new to GetStream and still learning. Here is a condensed version of what I'm using.
I have a python backend where I create user tokens:
client = stream.connect(...)
token = client.create_user_token(id)
return token
I then pass the token to the js frontend where it's used to retrieve feed activities for that user. I'm using the normal stream-js client and Jinja for the token and collection.id:
const client = stream.connect('apiKey', null, 'appID');
const collection = client.feed('collection', '{{ collection.id }}', '{{ token }}')
request = collection.get({ limit:10})
request.then((data) => {
...
)}
Here is my problem:
When I request activities for collection:4 everything works as would be expected. But when I do the exact same thing for collection:5 it suddenly gives
"You do not have permission to do this, you got this error because there are no policies allowing this request on this application." 403 NotAllowedException.
This only happens client-side, server-side it works fine. Could there be a problem in the jwt token used for authentication?
Thanks for any help.
By default, users can read their own feeds on the client side.
collection:4 is working because probably token is generated for the user with id 4 and it fails with permission error when that token is used for collection:5.
To have required policies in your app, please contact support with your app details and required policies/feed groups.
I am using the travel api from sabre and cannot make any http requests to any endpoint but 1. I don't understand what I am doing wrong. Im also not sure if I need a token since its just a test developer account and as I understand,I wouldn't need to require token?! if anyone has some experience with the saber api or api requests (maybe my code is wrong for other reasons) any help would be super much appreciated!! Thanks!!
Ps. I am using nodejs.
Api code that works:
var router = require('express').Router();
var SabreDevStudio = require('sabre-dev-studio');
var sabre_dev_studio = new SabreDevStudio({
client_id: 'V1:xxx',
client_secret: 'xxx',
uri: 'https://api.test.sabre.com'
});
var options = {};
router.get('/allcities', function (req, res) {
sabre_dev_studio.get('/v1/lists/supported/shop/themes', options, function (err, data) {
if (err) {
res.status(200).send(err);
} else {
res.status(200).send(data);
}
});
});
Api call (below) to get the lowest fares of picked destination doesn't work. In sabre's documentation I find this:
GET https://api.havail.sabre.com/v1/shop/flights/cheapest/fares/DFW HTTP/1.1
documentation: https://developer.sabre.com/docs/rest_apis/air/search/flights_to/
router.get('/lowestFare', function(req,res){
sabre_dev_studio.get('/v1/shop/flights/cheapest/fares/DFW HTTP/1.1', options, function(err, data){
if (err){
res.status(200).send(err);
}
else{
res.status(200).send(data);
}
})
})
What am I doing wrong?
Thanks!
In order to send requests to SOAP or HTTP sabre API's you need to have spoken to a Sabre account manager and/or signed a contract with Sabre. They will inform you which environments you have access and to which Sabre APIs you have access.
I presume you are only interested in the REST API's, namely the HTTP REST API 'Bargain Finder Max (BFM)', which is sabre's best-in-class low fare search product, used to search for the lowest available priced itineraries based upon a specific date. The 'Bargain Finder Max (BFM)' requires activation, documentation advises you to contact your Sabre Account Representative for assistance.
Firstly click here to obtain API key for test purposes. Register an account.
Obtain your personal 'key' and 'shared secret' after registration.
Click here for the test environment to get familiar with the REST API's.
The cheapest air search endpoint is part of the 'Air Search' HTTP REST API. This is an endpoint which supports HTTP GET requests to find the 20 lowest published fares available for a given destination (destination required; the destination parameter is a 3-letter IATA airport code or city code of the arrival airport e.g. LAX - Los Angeles). Also you submit a pointofsalecountry parameter which is just a 2-letter country code of the point of sale e.g. US.
Using the API explorer invoke a HTTP GET request to the following URI:
https://api.test.sabre.com/v1/shop/flights/cheapest/fares/LAX?pointofsalecountry=US
In terms of your Express.js JavaScript code, you've setup a middleware callback function for GET requests to '/lowestFare' which in turn seems to send a HTTP GET request to the following URL: '/v1/shop/flights/cheapest/fares/DFW HTTP/1.1' this is not a valid URL and doesn't seem to have any query string or request data / options sent with it.
See this GitHub repository with a complete examples for consuming sabre REST API's with Node.js. The readme file here also states: 'Please register at https://developer.sabre.com contact Sabre in order to obtain your own credentials.'
I started implementing 2 years ago my custom authentication in azure mobile service with node.js to use it in my jquery/cordova appery.io app. I have a database with users, passwords, etc and a login api in node.js backend that generates a valid jwt like this:
http://www.thejoyofcode.com/Exploring_custom_identity_in_Mobile_Services_Day_12_.aspx
http://chrisrisner.com/Version-1-of-the-Mobile-Services-JWT-token-has-been-deprecated
But now i have been migrated to azure app service and don´t know how to implement custom authetication with javascript.
At the examples above:
"iss":"urn:microsoft:windows-azure:zumo",
"ver":2,
"aud":aud,
But i have read that "aud" and "iss" must be my azure website and "sub" my own userId, to generate a valid jwt in my custom auth to use it in azure. Is it right?
https://shellmonger.com/2016/04/08/30-days-of-zumo-v2-azure-mobile-apps-day-5-custom-authentication/
The important thing is the token. There are some requirements for using 3rd party tokens with an Azure Mobile App:
It must follow the Json Web Token format
The user Id must be in the subject (sub) field
The audience (aud) and issuer (iss) must be known and configured
I do a call to my login API with ajax post and obtain a valid JWT token (http://jwt.io), but i don´t know the correct process to login and use azure services because i don´t know the correct way to use it on my app. I have changed MobileServices.Web.min.js to azure-mobile-apps-client.js in the app.
https://github.com/Azure/azure-mobile-apps-js-client
Can i use the jwt token created in azure node.js or exchange it for a session token and use client.login() method by JS SDK?
EDIT:
I see the light again adding to ajax POST
headers: {'X-ZUMO-AUTH': usuarioToken},
So my "authenticated users only" api works again with the old MobileServices.Web.min.js! It also works perfect with invokeApi method:
var mobileClient = new WindowsAzure.MobileServiceClient(urlApp,keyApp);
mobileClient.currentUser = {
userId: myCustomUserId,
mobileServiceAuthenticationToken: myCustomToken
};
mobileClient
.invokeApi('data', {
method: 'POST',
headers: {'X-ZUMO-AUTH': myCustomToken},
body: JSON.stringify(theData)
}) //end invokeApi
.done(
function (response) {
alert(response);
},
function (error) {
alert("error"));
}
); //end done
The mobileClient generated contains this data:
mobileClient= {"applicationUrl":"https://xxx.azure-mobile.net/","applicationKey":"hGhzxxx","version":"ZUMO/1.2 (lang=Web; os=--; os_version=--; arch=--; version=1.2.21003.0)","currentUser":{"userId":"Custom:25F600BB-xxxx-xxxx-xxxx-8329BCCF31D2","mobileServiceAuthenticationToken":"ey__rest of jwt token"},"_serviceFilter":null,"_login":{"_loginState":{"inProcess":false,"cancelCallback":null},"ignoreFilters":true},"push":{"_apns":null,"_gcm":null,"_registrationManager":null}}
I will try again wiht the new azure-mobile-apps-client.js
Any comment will be welcome
I have a javascript variable that I want to pass back to the server side, which I thereafter intend to use it as an access token to grant user access to other pages which requires this token.
I wonder how do I pass this javascript variable back to server, so I can set it to a session variable? Do I need to send it back using ajax?
this is the part of jQuery I use to retrieve the token from server
$(document).ready(function () {
$('#loginForm').submit(function(e) {
var blargh = $(this).find('input').serialize();
$.ajax({
type: 'post',
url: '/WebAPI/api/authenticate/login',
data: blargh,
success: function (data) {
$.each(data, function(index, token) {
$('#container').prepend('<input type="hidden" name="MY_HIDDEN_FIELD_NAME" id="MY_HIDDEN_FIELD_NAME" value="'+token+'">');
});
},
error: function(jqXHR, status, errorThrown) {
alert("Error " + status + "\nError Thrown" + errorThrown )
},
});
e.preventDefault();
});
});
To pass back an additional item in the AJAX POST, you could add it like this...
var blargh = $(this).find('input').serialize();
blargh.someItem = "value";
Bear in mind that this only works when the form is submitted using AJAX, so not where JavaScript isn't available or is disabled.
All the normal security disclaimers apply!
I would recommend sending you the acess token in request headers when u are sending a ajax request
xhr.setRequestHeader('custom-header', 'value');
and on the server side you can fetch the request header
Couldn't you pass it back as either a hidden form element or pass it back in the query string of a ajax postback?
Example of a hook to get the post back value in global.asmx
protected void Session_Start(object src, EventArgs e)
{
if(!string.IsNullOrEmpty(Request.Form["MY_HIDDEN_FIELD_NAME"]))
{
Session["MY_SESSION_NAME"] = Request.Form["MY_HIDDEN_FIELD_NAME"]
}
}
First - why is your client generating the token (I hope I've understood you correctly there)? The server should generate the token and the client must then be responsible for maintaining it.
If it's an API token that'll only ever be used in the browser from javascript, then I recommend using an authentication cookie - all browsers know how to handle them and you can also easily expire them server-side if you no longer want to allow a particular token to have access (that's quite an important point). Also I strongly recommend against relying on server-side session to maintain the authentication session.
Authentication tokens should ideally be stateless (just like in Forms Authentication's cookie) - the burden of proof is on the client to send you a correct token, with that token containing the information you need to re-initialise the current requests state with the correct user.
If, however, it's a general purpose API for any type of client then you should allow the client to send the token to you in the query string of all requests at a very minimum. You should also support taking it in the request header as well - clients that can easily support setting request headers often prefer to because it then hides the auth token from the URL and makes formatting requests easier (there's also the potential to max out a web server's query string limit if the token is big enough).
I then recommend you look, at a minimum, at overriding MVCs AuthorizeAttribute (there are 2 - one for the 'standard' MVC 4 pipeline and one for the new Web API pipeline, & they would both need to be done if you are using both technologies. The link is for the MVC 4 one) to crack out your cookie/header/query string value. In there you can get the value, decrypt the token, identify the user and set the roles. The core code of that attribute then contains the logic for denying a request based on whether the user is authenticated/has a certain role/is a certain user.