I'm creating an HTML 5 client to app services, however our app services are enterprise so behind an apigee gateway proxy ( not directly through api.usergrid.com).
I'm initializing like this:
$(function() {
var client = new Apigee.Client({
orgName:'myorg',
appName:'sandbox',
monitoringEnabled:false,
URI:'https://prod.OURURL.com/appservices/v1'
});
var username = "myusername";
var password = "mypass";
client.login(username, password,
function (err) {
if (err) {
console.log('There was an error logging you in.');
} else {
//login succeeded
client.getLoggedInUser(function(err, data, user) {
if(err) {
//error - could not get logged in user
console.log("error on lvl2");
} else {
if (client.isLoggedIn()){
appUser = user;
console.log('data')
// showFullFeed();
}
}
});
}
}
);
});
I'm immediately getting:
Error: Apigee APM configuration unavailable.
and then of course:
There was an error logging you in.
using the trace tool in the proxy I can see this errorr on the request to /proxy_path/org/app/apm/apigeeMobileConfig
{"timestamp":"1398263318219","duration":"0","error":"illegal_argument","exception":"java.lang.IllegalArgumentException","error_description":"JSON source MUST not be null"}
of course this is all called by the above code.
thank you in advance.
[EDIT FOR MORE INFORMATION]
Just tested with my own private org, so not setting the options.URI param, the second log message is normal as I had not created the app user, however the initialization is NOT working on the enterprise org, so this:
var client = new Apigee.Client({
orgName:'myorg',
appName:'sandbox',
monitoringEnabled:false,
URI:'https://prod.OURURL.com/appservices/v1'
});
is returning the APM error.
It seems you need to enable some of the options in the app services app ( inthe configuration option) for this api call to return something, thus enabling the sdk.
Related
I am using the JSForce docs in order to create a Javascript app to connect to my Salesforce org. My code is as follows:
var jsforce = require('jsforce');
var conn = new jsforce.Connection({
loginUrl : 'https://test.salesforce.com'
});
var username = 'my-username#domain.com';
var password = 'mypassword';
conn.login(username, password, function(err, userInfo) {
if (err) { return console.error(err); }
console.log(conn.accessToken);
console.log(conn.instanceUrl);
console.log("User ID: " + userInfo.id);
console.log("Org ID: " + userInfo.organizationId);
});
However, when I run it, it appears to do nothing at all. I would expact to see either the access token etc to be logged to indicate success, or an error to indicate failure. But nothing is logged at all.
When I check the login history on my Salesforce org, I can see the attempts, they are successful.
What's going on?
The answer is simple. The instructions are for jsforce v1.x, but I had jsforce 2.x (beta). Fixed by doing this:
npm install jsforce#1.11.0
I'm using the node-linkedin npm package to authenticate and read information about from other users (name, job title, company name, profile pic, shared connections). I can correctly receive and store the access token (verified in my own LinkedIn profile's approved apps & console logging the token), but I am unable to return any of the requested information. My calls are copied & pasted from the package docs, but it returns the following:
2018-02-28T03:46:53.459839+00:00 app[web.1]: { errorCode: 0,
2018-02-28T03:46:53.459843+00:00 app[web.1]: message: 'Unknown authentication scheme',
2018-02-28T03:46:53.459845+00:00 app[web.1]: requestId: '3B55EVY7XQ',
2018-02-28T03:46:53.459847+00:00 app[web.1]: status: 401,
2018-02-28T03:46:53.459848+00:00 app[web.1]: timestamp: 1519789613443 }
I have included my routes below. Solely for the purpose of testing, myToken and linkedin are server-side global variables to the linkedin-controller scope. (I understand this will need to change for the final product, which is a student project.)
app.get('/companies', function (req, res) {
console.log(linkedin.connections.config.accessToken);
linkedin.companies_search.name('facebook', 1, function(err, company) {
console.log('Merpy merpy mc merpers'
,company);
// name = company.companies.values[0].name;
// desc = company.companies.values[0].description;
// industry = company.companies.values[0].industries.values[0].name;
// city = company.companies.values[0].locations.values[0].address.city;
// websiteUrl = company.companies.values[0].websiteUrl;
res.redirect("/");
});
});
app.get('/companies2', function (req, res) {
linkedin.companies.company('162479', function(err, company) {
console.log(company);
res.redirect("/");
});
});
app.get('/connections', function (req, res) {
linkedin.connections.retrieve(function(err, connections) {
console.log(connections);
res.redirect("/");
});
});
This is my authorization code, which appears to work:
app.get('/auth', function (req, res) {
// This is the redirect URI which linkedin will call to and provide state and code to verify
/**
*
* Attached to the redirect_uri will be two important URL arguments that you need to read from the request:
code — The OAuth 2.0 authorization code.
state — A value used to test for possible CSRF attacks.
*/
//TODO: validate state here to secure against CSRF
var error = req.query.error;
var error_description = req.query.error_description;
var state = req.query.state;
var code = req.query.code;
if (error) {
next(new Error(error));
}
/**
*
* The code is a value that you will exchange with LinkedIn for an actual OAuth 2.0 access
* token in the next step of the authentcation process. For security reasons, the authorization code
* has a very short lifespan and must be used within moments of receiving it - before it expires and
* you need to repeat all of the previous steps to request another.
*/
//once the code is received handshake back with linkedin to send over the secret key
handshake(req.query.code, res);
});
function handshake(code, ores) {
//set all required post parameters
var data = querystring.stringify({
grant_type: "authorization_code",
code: code,
redirect_uri: OauthParams.redirect_uri,//should match as in Linkedin application setup
client_id: OauthParams.client_id,
client_secret: OauthParams.client_secret// the secret
});
var options = {
host: 'www.linkedin.com',
path: '/oauth/v2/accessToken',
protocol: 'https:',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(data)
}
};
var req = http.request(options, function (res) {
var data = '';
res.setEncoding('utf8');
res.on('data', function (chunk) {
data += chunk;
});
res.on('end', function () {
//once the access token is received store it
myToken = JSON.parse(data);
linkedin = Linkedin.init(myToken);
ores.redirect("/");
});
req.on('error', function (e) {
console.log("problem with request: " + e.message);
});
});
req.write(data);
req.end();
}
In my troubleshooting research, it seems I need to pass the token into the request; however, I can't find anywhere or any way to do so in the package. And with as many daily downloads as the package has, I can't possibly be the only one to experience this error. The author's Issues section of GitHub were unhelpful, as were other searches for this package's error.
My deployment: https://linkedin-api-test.herokuapp.com/
(When visiting the deployment, you must click the blue "Want to
connect to LinkedIn?" link prior to manually changing the uri
according to the routes. The results will also only display in the
Heroku logs, which is most likely largely unhelpful to you. It was
supposed to be a simple test, so I simply stole the front end from my
prior project.)
My Repo: https://github.com/SteveSonoa/LinkedIn-Test
node-linkedin Docs: https://github.com/ArkeologeN/node-linkedin/blob/master/README.md
This is my first question I haven't been able to find the answer to; I apologize if I left out anything important while asking. Thank you in advance for any help!
The solution was to pass the following token code into the linkedin variable instead of simply passing myToken:
linkedin = Linkedin.init(myToken.access_token || myToken.accessToken);
I don't understand the downvote, as no comments were left; I apologize if I left out important or generally expected information, as this was the first question I've asked. I want to make sure the solution is posted for anyone coming after me with the same issue. This issue is now solved.
I'm doing an user management with Cognito webservice from Amazon.
Everything is running smoothly on local but everything crash when I use it on a Wamp server and I can not figure out why.
I'm doing as of now my registration directly on my controller like this :
AWSCognito.config.region = 'eu-west-1';
var cognitoUser;
var poolData = {
UserPoolId: 'eu-west-1_XXXXXXXX',
ClientId: '4dkagd3xxxxxxxxxxxxxx'
};
AWSCognito.config.credentials = new AWSCognito.CognitoIdentityCredentials({
IdentityPoolId: 'eu-west-1:xxxxxx-xxxx-xxx-xxxxx-xxxxxxxxxx',
});
var userPool = new AWSCognito.CognitoIdentityServiceProvider.CognitoUserPool(poolData)
userPool.signUp($scope.username, $scope.password, attributeList, null, function(err, result) {
if (err) {
alert(err);
return;
} else {
alert('successfully registered');
routeService.goToView('/users-confirmation');
}
});
The mysterious thing is that I never get any of the two alerts (error or success) and I'm directly redirected to my main page...
Does anyone know why and how can I fixe it ?
I have an authentication service built on IdentityServer3 and a WebAPI Shopper service that is secured with IdentityServer Bearer Token Authentication. I've built a simple MVC client app that can access the Shopper service either as a client app with an access token or on behalf of an authenticated user with an identity token. The Shopper service will return more data to the authenticated user.
Now I'm trying to build a JavaScript client that does the same two-tier level of access to the Shopper service. So far, following some IdentityServer3 JavaScript client examples, I've got the JS client successfully calling the Shopper service on behalf of an authenticated user. (I will probably need to reorganize the code a bit to accommodate the non-authenticated scenario, but that shouldn't be too difficult.) What I don't know how to do from the JavaScript code is request the client access token from the Authentication service, i.e. the JavaScript equivalent of the server-side TokenClient.RequestClientCredentialsAsync("shopper-service") in the MVC client. Does anyone know how to request that token from JavaScript or know of a sample that shows how to do it? Here's the JavaScript code that I have so far for the authenticated case and below that is the working MVC client code:
function display(selector, data) {
if (data && typeof data === 'string') {
data = JSON.parse(data);
}
if (data) {
data = JSON.stringify(data, null, 2);
}
$(selector).text(data);
}
var settings = {
authority: 'https://localhost:44332',
client_id: 'js-sample',
popup_redirect_uri: 'http://localhost:15264/popup.html',
response_type: 'id_token token',
scope: 'openid orvis-shopper-service',
filterProtocolClaims: false
};
var manager = new Oidc.UserManager(settings);
var user;
manager.events.addUserLoaded(function (loadedUser) {
user = loadedUser;
display('.js-user', user);
});
$('.js-login').on('click', function () {
manager
.signinPopup()
.catch(function (error) {
console.error('error while logging in through the popup', error);
});
});
$('.js-call-api').on('click', function () {
var headers = {};
if (user && user.access_token) {
headers['Authorization'] = 'Bearer ' + user.access_token;
}
$.ajax({
url: 'https://localhost:44368/api/Shopper/{5FA13934-AD20-4AB2-A386-11653D71AE55}',
method: 'GET',
dataType: 'json',
headers: headers
}).then(function (data) {
display('.js-api-result', data);
}).catch(function (error) {
display('.js-api-result', {
status: error.status,
statusText: error.statusText,
response: error.responseJSON
});
});
});
The client app code works as I intend and looks like this:
public async Task<ActionResult> Index()
{
string tokenValue;
var user = User as ClaimsPrincipal;
if (user.Identity.IsAuthenticated)
{
tokenValue = user.FindFirst("access_token").Value;
}
else
{
var tokenResponse = await GetTokenAsync();
tokenValue = tokenResponse.AccessToken;
}
var result = await CallShopperService(tokenValue);
ViewBag.Json = result;
return View();
}
private async Task<TokenResponse> GetTokenAsync()
{
var client = new TokenClient(
"https://localhost:44332/connect/token",
"mvc-sample-svc",
"mvcsamplesecret");
return await client.RequestClientCredentialsAsync("shopper-service");
}
private async Task<string> CallShopperService(string token)
{
var client = new HttpClient();
client.SetBearerToken(token);
var json = await client.GetStringAsync("https://localhost:44368/api/Shopper/{5FA13934-AD20-4AB2-A386-11653D71AE55}");
return json;
}
JS implicit client is also able to get back you access token, as long as you set token in response_type which you did according to your pasted script.
The Oidc-client.js builds up an authorize challenge URL and redirect browser to it, which is where login flow begins. After user signs in, then they get bounced back to your client page following same redirect path. When your client page loaded (depends on which flow your client is configured, it should be hash fragment by default), oidc-client grabs token from URL (everything after #) and transforms it into JSON object then save in local storage (which means you can check it there too).
I would suggest following method to help you debug:
Turn on traffic monitoring tool (e.g. fiddler) to ensure response that returned back from your identity server after login does contains access token (you can decode token string using https://jwt.io/), if not, check if authorize request url formed correctly
If response returned from identity server does contains access token , then you can debug oidc-client.js javascript by setting a breakpoint at _signinEnd method
Hope it helps
Updated, from comment section
For "anonymous token" senario? See this example if that is what you are looking for github.com/IdentityServer/IdentityServer3/issues/1953
I stuck with one problem.
I`m trying integrate PayPal button with meteor app. But for full functionality i need to handle with IPN.
Because i have to know at least transaction status.
I already have business account and i turned on IPN on path:
http://domein.com/ipn
I tried use PayPal documentation, but it doesn't help too.
I spend two days and still can't find anything helpful.
Maybe someone know how to implement IPN listener in meteor app?
EDIT: Update for Meteor 1.3+
I published a package that vastly simplifies the process. The package is planefy:paypal-ipn-listener.
First, install then package:
$ meteor add planefy:paypal-ipn-listener
Then, in server code:
import { IpnListener } from 'meteor/planefy:paypal-ipn-listener';
const listener = new IpnListener({
path: '/mypath',
allow_sandbox: true // in development
});
listener.onVerified((err, ipn) => console.log(ipn));
listener.onError((err) => console.log(err));
See the readme for more options.
ORIGINAL ANSWER
I did a lot of head scratching trying to figure this out too.
First, add the following packages, if you don't already have them.
meteor add meteorhacks:npm
meteor add meteorhacks:picker
If you are using iron:router, then you actually don't need need meteorhacks:picker (See update at bottom)
Create a package.json in your application root (if it doesn't already exist), and add the following to tell meteorhacks:npm which npm packages need to be installed:
{
"paypal-ipn" : "3.0.0",
"body-parser": "1.14.1",
}
In server code, configure Picker to properly parse JSON requests/responses:
const bodyParser = Meteor.npmRequire('body-parser');
Picker.middleware(bodyParser.urlencoded({ extended: false }));
Picker.middleware(bodyParser.json());
Also in server code, define a Picker route to handle incoming IPN messages
Picker.route('/ipn', function(params, req, res, next) {
res.writeHead(200);
const ipn = Meteor.npmRequire("paypal-ipn");
// create a wrapped version of the verify function so that
// we can verify synchronously
const wrappedVerify = Async.wrap(ipn,"verify");
let verified = false;
// only handle POSTs
if (req.method === "POST") {
// PayPal expects you to immeditately verify the IPN
// so do that first before further processing:
try {
//second argument is optional, and you'll want to remove for production environments
verified = wrappedVerify(req.body, {"allow_sandbox" : true});
} catch (err) {
// do something with error
}
if (verified === 'VERIFIED') {
let payment = req.body;
// do stuff with payment
}
}
res.end();
});
Update: If you are using iron:router, you don't need to use Picker. You can just define a server only router directly with iron:router, like so:
Router.map(function () {
this.route('ipn', {
path: '/ipn',
where: 'server',
action: function() {
var ipn = Meteor.npmRequire("paypal-ipn");
var wrappedVerify = Async.wrap(ipn, "verify");
var request = this.request;
var verified;
if (request.method !== 'POST') {
this.next();
} else {
try {
verified = wrappedVerify(request.body, {"allow_sandbox" : true});
} catch (error) {
//do something with error
}
if (verified === "VERIFIED") {
var payment = request.body;
//do something with payment
}
this.next();
}
}
});
});