Connection between nativescript and MongoDB (mongoose) - mongodb

I am new in mobile development world and right now trying to understand few basic things.
I did a simple login nativescript app and from backend side did a login logic with mongoose (MongoDb) and express. But now I don't know how to proceed... How do I connect between backend and app?
Thank you in advance,
Emil

You need to expose an API from your backend, I'll assume you have done this (or can find this out - it's very well documented).
So from the client {N} you will need to access the API, calling whichever end-points you need. If you were using a JWT type approach, you should use the http module in nativescript, which might look something like this:
var http = require("http");
var result;
http.request({
url: "https://myBackend.org/api/post",
method: "POST",
headers: { "Content-Type": "application/json" },
content: JSON.stringify({ username: "ValueOne", password: "ValueTwo" })
}).then(function (response) {
result = response.content.toJSON();
console.log(result); //result.message would have the clients auth token
}, function (e) {
// console.log("Error occurred " + e);
});
You could then store the token (in persistent storage with the application-settings module) and add it to the header of any request to a different API endpoint to interact with your backend as an authenticated user.
Alternatively, you can use one of the cloud backend SDKs, e.g. Azure Mobile Services or Firebase which make your life much easier.

Related

Making HTTP requests from within MongoDB Atlas App Services

We are currently using the Third-party HTTP Service provided by MongoDB in order to make HTTP requests to the outside world from within our app running in Atlas App Services. As per their documentation, this will be deprecated in December 2022.
However, I can't find an alternative for the future - what will be the preferred way to make HTTP requests from within Atlas App Services Apps?
I was in similar situation before as you are.
But then I realised that App Service team actually simplifies it by adding support for dependencies.
So, I can import standard axios library and starts using it seamlessly as
exports = async function(arg){
const axios = require('axios'); // is allowed here
axios.get('https://coderower.com')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.log(error);
});
return {success: true}
};

Unable to do a Nuxt axios post

I have spent some hours trying to figure out my problem without any success.
before reading the explanation
My nuxt site generates dynamic content and works well on client side but for SEO to work and social media shares render dynamic content i need to move my app to SSR. This axios post request do work on client side rendering but does not on SSR and I don't understand the reason and I need help to understand it.
Thanks
For starters I am building a Nuxt app that consumes Drupal as a CMS using a fully decoupled approach and I have been using it for several VUE apps without problem and now I need to do them on Nuxt with a SSR approach because I need heavy SEO on the sites. With Nuxt the same request against oauth/token on drupal doesn't work and I have gone from the complex structure we had to the simple one using both Axios and Nuxt/Axios without any success and alway getting a 400 error code.
I need to run this code first on my app so I can get drupal access token and do some request for data.
Code on store
export const actions = {
async nuxtServerInit({dispatch}, vuexContext, context, app){
await dispatch("setToken");
},
async setToken({ commit, dispatch, getters }, context) {
//prep form data to send
const FormData = require('form-data');
const body = new FormData();
body.append("param1", apiConfig.getValue("param1"));
body.append("param2", apiConfig.getValue("param2"));
body.append("param3", apiConfig.getValue("param3"));
body.append("param4", apiConfig.getValue("param4"));
body.append("param5", apiConfig.getValue("5"));
await this.$axios.$post(url, body)
.then(({data}) => {
//code to process data
commit("SET_TOKEN_DATA", data);
}).catch(error => {
console.log(error)
}).finally(() => {
console.log("FINALY");
});;
}
Some updates
base url is defined on nuxt.config as
// module options for axios
axios: {
baseURL: 'mysite.com'
},
I have tied on http request the following request using both axios and nuxt/axios, I will write short request just to show what I edid
await this.$axios.$post('mysite.com/oauth/token', body)
await this.$axios.$post('/oauth/token', body)
await this.$axios.$post('oauth/token', body)
I have also tried to use
const api = $axios.crate({
baseURL: 'url'
})
api.$axios.post('oauth/token', body)
another updated
Crated a Client Side Nuxt app and the request works.
Fix it, after literally 16 hours trying. When multiform post data you need to send FormData headers on the post and again, this works without any issues using CSR on VUE and Nuxt.
await this.$axios.$post(url, body, { headers: body.getHeaders()}).yada
I don't know if it's Axios or Nuxt the one doing this but I followed a breadcrumb trail to this post https://github.com/axios/axios/issues/318

Securing a restful API verifying clients with JWT

I have a RESTful API using JWT for authentication purposes. The first call I receive from a client is the /login call, with the following payload (no headers)
{
"username" : xxxx,
"password": wwww
}
The server verifies if the user is registered and then returns a signed JWT to the client in order to be received in the next calls.
I wonder if this is secure enough. I don't check anywhere if the client sends me a client id / client secret (like in OAuth) so I cannot verify if this call is from my webapp / apps or if it is an external client which I don't know about. I want to know if it makes sense to implement this behavior using JWT and how to implement it.
(I know how to do it with OAuth2 but I don't want to move now from JWT authentication)
Thank you!
If I understood you correctly, you should create a function somewhat similar to this:
function verify(req, res, next) {
const token = req.header('x-auth-token');
if (!token) {
return res.status(401).json({
msg: 'No token, auth denied'
});
}
try {
const decoded = jwt.verify(token, config.get(YOUR_SECRET_GOES_HERE));
req.user = decoded.user;
next();
} catch (err) {
res.status(401).json({
msg: 'Token is not valid'
});
}
}
For all secured API endpoints you should apply it like this:
router.get('/anyuserinfo', verify, (req, res) => ...
And that is it. The function will send 401 response if no token is provided.
I think I found another Stackoverflow question that answers mine:
JWT (Json Web Token) Audience "aud" versus Client_Id - What's the difference?
In a nutshell, client_id and client_secret should be sent on headers to the server to be validated before sending a new JWT token.

Current method to get new access token from refresh token

I see some questions about this with solutions that seem to be deprecated in the Google APIs Node.js Client OAuth API (e.g., this and this).
There's no documentation I can see regarding using the refresh token to get a new access token (docs section). In an issue from early 2017, someone mentions getting off the oauth2Client.credentials property, but it looks like that's within a call to one of the other APIs wrapped in the package.
In my use case, I'm querying the Google My Business (GMB) API, which is not wrapped in there, but I'm using the OAuth piece of this package to authenticate and get my tokens.
My request to the GMB API (using the request-promise module), looks something like this:
function getLocations () {
return request({
method: 'POST',
uri: `${gmbApiRoot}/accounts/${acct}/locations:batchGet`,
headers: {
Authorization: `OAuth ${gmbAccessToken}`
}
})
.then(function (response) {
console.log(response);
})
.catch(function (err) {
// ...
});
}
I don't think I can pass the oauth2Client into the headers for authorization like in the issue response. Is there a way to directly request a new access_token given that I have my refresh token cached in my app?
Update: Solved! Thanks to Justin for the help. Here's what my working code is looking like:
oauth2Client.setCredentials({
refresh_token: storedRefreshToken
});
return oauth2Client.refreshAccessToken()
.then(function (res) {
if (!res.tokens && !res.credentials) {
throw Error('No access token returned.');
}
const tokens = res.tokens || res.credentials;
// Runs my project-level function to store the tokens.
return setTokens(tokens);
});
If you have an existing oauth2 client, all you need to do is call setCredentials:
oauth2client.setCredentials({
refresh_token: 'REFRESH_TOKEN_YALL'
});
On the next call that goes through the client, it will automatically detect there is no access token, notice the refresh token, and go snag a new access token along with it's expiration date. I outlined some docs and code around this in the issue you opened up on GitHub :P
https://github.com/google/google-api-nodejs-client/pull/1160/files
Hope this helps!
I wanted to add in my learning, to the community, in case it helps anyone out there struggling with this too. The above answers were correct, but I discovered one other attribute.
Namely, I was calling my credentials like this:
oAuth2Client.setCredentials(JSON.parse(authResults));
my authResults, is defined as this:
const authResults = fs.readFileSync(TOKEN_PATH);
This results in several fields being filled in to the results variable:
[
'access_token',
'refresh_token',
'scope',
'token_type',
'expiry_date'
]
Now here's the nuance...if the access_token AND the refresh_token are both given to the setCredentials call, the refresh-token is ignored. Changing to the above answer, where I send in only the refresh token:
oAuth2Client.setCredentials({ refresh_token: creds['refresh_token'] });
Worked like a champ! Hope this finds its way and helps someone else.

Authenticate on Application Insights REST API with AAD

So far I used successfully Application Insights REST API for getting metrics with X-Api-Key header.
https://api.applicationinsights.io/beta/apps/xxxxxxxxxx/metrics/customMetrics%2FmetricName?timespan=PT2H&interval=PT20M&aggregation=min
However with our new dashboard, crawling several metrics, we hit hard the 1500 request/api key limit.
Some suggest to play around with several api keys, but I would like to prevent this approach.
According to documentation, authenticate with AAD would remove the daily cap (https://dev.applicationinsights.io/documentation/Authorization/Rate-limits)
But I fail to authenticate with AAD (in nodejs, but I suspect it's the same in any language)
I used adal-node with a simple app, I successfully get a token, however I'm not able to forward it to the Request
var context = new AuthenticationContext(authorityUrl);
context.acquireTokenWithClientCredentials(resource, clientId, clientSecret, function(err, tokenResponse) {
if (err) {
console.log('well that didn\'t work: ' + err.stack);
} else {
console.log(tokenResponse);
request({'url' : 'https://api.applicationinsights.io/beta/apps/xxxxxxxxx/metrics/customMetrics%2Fmetrics?timespan=PT2H&interval=PT20M&aggregation=min',
headers: {
'Authorization': 'Bearer ' + tokenResponse.accessToken
}
}, function (error,response,body){
console.log(body);
});
}
});
I'm getting following error message
The provided authentication is not valid for this resource
The given API Key is not valid for the requested resource
I suspect I miss something :)
We don't support AAD in our REST API directly. Your resource is managed by the Azure Resource Manager, and only it can validate a certain user has access to this resource. API Keys are our way of short circuiting the authorization directly to a resource, instead of in the user context.
You gave this AAD app access to this resource as yourself, so the authentication is still in the context of a user. The call has to be made to ARM instead: 'https://management.azure.com/subscriptions/xxxxxx/resourcegroups/xxxxx/providers/microsoft.insights/components/xxxxx/api/metrics/customMetrics%2Fmetrics?api-version=2014-12-01-preview&timespan=PT2H&interval=PT20M&aggregation=min'
Documentation is linked here - though not explained explicitly: https://dev.applicationinsights.io/documentation/Authorization
This will get you a higher rate-limit, and still return the same response as the REST API.