JSON Web token(JWT) as API key in analytics service - json

We are running analytics service for web. Each application created inside the service is provided with the script and API key to collect the metrics. Users have to copy the script into their HTML to monitor the site. The API key is public and anyone can see it from HTML code. So anyone can use the API key to send fake data into account.
We heard that JSON Web token(JWT) is a better way to replace session cookies. Will JWT can solve this issue?

By definition, such a code snippet must be inside the HTML code. In that sense it makes no difference whether you use an API key or a JWT token. Both can be read and used.
But you can embed an expiration time in the JWT token. This way, a copy/pasted JWT token out of the html page is only usable for a relatively short time.
It won't stop determined people from inserting fake data, as they can write a script to read a "fresh" JWT token by regularly downloading the html page.
So: it helps only a little bit.

Related

How to use OAuth 2.0 with a Google Apps Script library, with a static redirect URL?

I can't figure out how to make a shared Google Apps Script library, that uses OAuth 2.0.
The problem is that the usercallback redirect URL changes, every time I use the library in a different script. However, that means I'd need to add a new app and whitelisted redirect URL to Asana for each spreadsheet I use the script in. I'm using https://github.com/googlesamples/apps-script-oauth2.
Is there a way to always authenticate with the same redirect URL, so that the library I make can be used from any script, without registering a new redirect URL in Asana?
I'm a Developer Advocate here at Asana. If I understand your question correctly, then yes, you'll have to handle the callback separately for each script. For security reasons, we validate that the OAuth app registration registers the same url as an integration actually requests when authenticating. If this weren't true, for instance, it'd be possible to create a malicious script that uses the client_id from a legitimate script but asks for the redirect to go to its own credential-grabbing endpoint. This is fixed if the app that got the client_id on app registration also specifies precisely which endpoint should be the legal endpoint to redirect to. That means each OAuth app needs to have its own unique and consistent redirect URL :(
I suppose you could possibly create a single "router" Google Apps script which would set the state parameter with some user/script pair when hitting Asana's oauth_authorize endpoint and forward the user credentials on to the script that exists behind the router script based on that user/script pair when the response comes back, but it's not super trivial.
One final option would be to use a Personal Access Token to access Asana's API. This one token can be used by an unlimited number of scripts for access. The downside is that this token "looks like you", that is, it takes action on behalf of not a third party user but you yourself - your scripts would be an automated version of the user whose Personal Access Token they use. This can be mitigated to some extent by creating a "bot account" to access our API and giving it access inside of Asana to the projects or teams you want to gather data on. The other downside to this approach is that every script that uses the personal access token will break if you ever revoke the one token, so if that ever happens by either intent or accident, you'll have to update the Personal Access Token information in every script that uses it.
Hopefully this helps you to evaluate the options and choose which one of these options works best for your script.

JSON Web Tokens in Node Js Express application

So I have an API using Express in NodeJS and I want to secure it so only I or known clients can use it. I found about JSON Web Tokens but not sure how to keep the key secure if I'm making AJAX requests to the API from a web client using JQuery for example. People will be able to get the key and make request themselves right?
How do I prevent this? Or have I misunderstood the concept of JSON Web Tokens.
Other smaller question, I found the jsonwebtoken npm package which seems popular and you can sign a web token and verify one. How does the verification work? I know you pass a secret but the same secret is used for multiple signed keys right? I originaly thought I store the key in a database or something and verify if the provided key in the request is in my database but that does not seem to be the case as the you do not store the key.

How to hide API key in JSON API request

I am creating an API server which serves a card number validation and transaction insert.
Sample API URL = http://mydomain.com/api.json?cardnumber=2342343244&api_key=jhj67asd234tgbh123
Existing system:
I am providing an api key to client systems (say ebay.com). I am providing a discount if the user have a valid card. So my client will provide a form field to his end users to enter a valid card number.
Problem:
My client is writing ajax request to my domain to process the validation. The problem is the api key is visible in console and anyone can do the request outside of the client system (security loss).
Propose system: Please propose a system where my api key is hidden, so that the request will be processed securely. The solution may be any other way of writing an API.
I have less knowledge about API. Any help will be appreciated.
In my experience there isn't an easy way of doing this.
The only method I know about is providing the client with a one-time key. As soon as its used, it expires and the client will need a new one.
In this manner it doesn't matter that the key is visible in the console as its only ever going to be valid for a single request.
I hope that helps but I'd love to hear about any suggestions anyone else has.

How to authorize with oauth 2.0 from appscript to Google APIs?

I'm playing around with AppScript and try to get an oAuth 2.0 access token.
Any sample out there how to get this working in AppScript?
I am working on a cleaner tutorialized version of this, but here is a simple Gist that should give you some sample code on how things would work -
https://gist.github.com/4079885
It still lacks logout, error handling and the refresh_token capability, but at least you should be able to log in and call a oAuth 2 protected Google API (in this case its a profile API).
You can see it in action here -
https://script.google.com/macros/s/AKfycby3gHf7vlIsfOOa9C27z9kVE79DybcuJHtEnNZqT5G8LumszQG3/exec
The key is to use oAuth 2 Web Server flow. Take a look at getAndStoreAccessToken function in the gist to get the key details.
I hope to have this published in the next few weeks but hopefully this will help in the mean time.
UPDATE - adding in info on redirect_uri
The client secret is tied to specific redirect URIs that the authorization code is returned to.
You need to set that at - https://code.google.com/apis/console/
The highlighted URI needs to match the published URI (ends in /exec). You get the published URI from the script editor under Publish -> Deploy as web app. Make sure you are saving new versions and publishing the new versions when you make changes (the published URI stays the same).
I've modified the example above to use the newish state token API and the CacheService instead of UserProperties, which is now deprecated. Using the state token API seems to make things a little more secure, as the callback url will stop accepting a state token after a timeout.
The same caveats apply. Your redirect URIs have to be added to your (script) project in the developer's console, meanwhile you have to yank the CLIENT_SECRET and CLIENT_ID from the console and paste them in. If you're working within a domain, there don't seem to be any guarantees on what URL will be returned by ScriptApp.getService().getUrl(), so I wound up basically having it get the address dynamically, then waiting for to fail on the the (second) redirect, and then hard-coded the resulting URI.
https://gist.github.com/mclaughta/2f4af6f14d6aeadb7611
Note that you can build an OAuth2 flow using this new API, but it's not a complete sample yet:
https://developers.google.com/apps-script/reference/script/script-app#newStateToken()
In particular, you should not pass 'state' directly to the /usercallback URL yourself, because the OAuth2 service provider is responsible for round-tripping the 'state' parameter. (Instead, you pass 'state' to the auth URL, and the service provider automatically attaches it to the callback URL.)

How to provide application-wide authorization to HTTP JSON API for consume it within the browser?

I'm currently working in HTTP JSON API for a touristic webapp. The webapp will be developed by a third-party company and it'll consume the API within the browser.
So I need for the API some sort of authentication to the third-party webapp can consume it. I've been researching a little bit about OAuth, but with this, I have a solution for a user-wide but not for application-wide authorization.
Because the webapp will consume the API within the browser(with Ajax), I'm concerned they will have to put the credentials to consume the API in the user browser.
Another solution would be place the credentials for the API in the server-side, but this don't depend on me.
You could always use something similar to google's method, with a client ID and then a private key used to generate a signature.
https://developers.google.com/maps/documentation/business/webservices#generating_valid_signatures
That page has some code samples as well.