Tweet input field from website in Javascript - javascript

I have an input field on my webpage that I would like to allow users to tweet. I know I can do this using Oauth but because I am using JavaScript it is insecure since my id and secret would be visible. Is there a better way to do this?
The way I am doing it now is something like this:
var accessor = {
token: "...",
tokenSecret: "...",
consumerSecret: "..."
consumerKey : "...",
};
//create message with input field text
var message = {
action: url,
method: "GET",
parameters: {...}
};
OAuth.completeRequest(message, accessor);
OAuth.SignatureMethod.sign(message, accessor);
url = url + '?' + OAuth.formEncode(message.parameters);
But this will make my secrets visible.
Thanks

In the OAuth model, there are three parties: the server or "resource manager," the app or "client", and the user or "resource owner".
In your case, the "client" is the web app, the thing you are building. The resource manager is twitter, and the user is the resource owner. Maybe it bears repeating: the resource that is owned and managed is the tweet stream.
OAuth allows the client to submit requests to the resource manager on behalf of the resource owner. Translated to your scenario, that means your app (web app) can submit tweets on behalf of the user.
The web app model and its distributed computational model, with some code running on the server (PHP, Ruby, ASPNET, or whatever it is) and some code running on the client (Javascript) sort of confuses the issue a little.
As you point out, you can "do" oauth by embedding the key and secret in JS code. You rightly point out that this exposes stuff you don't want to expose.
The obvious alternative is to embed that stuff into the server-side code. This requires that the connection to twitter occur between the server and twitter, not between the browser and twitter.
When the user wants to tweet, use an ajax call from the browser to a piece of code on your server, let's call it mytweet.php. This is a script you write, which then does the OAuth dance and sends a status update to twitter.com on behalf of the user.
ya follow?

Related

Why my geoip query doesn't work in my production server?

I'm getting a hard time making Maxmind's geolite2 geolocation work on client side.
First I found this page: https://dev.maxmind.com/geoip/geolocate-an-ip/web-services?lang=en
And tried to use the urls in the curl command with authentication with my generated license key:
let geoData = axios.get('https:///geolite.info/geoip/v2.1/country/me?pretty', {
auth: {
username: <myuser>,
password: <mylicensekey>
}
});
this works in node but in client-side I get a CORS error.
then I found this other page: https://dev.maxmind.com/geoip/geolocate-an-ip/client-side-javascript?lang=en
It worked but I didn't want to use a non-npm packaged lib, so I inspected the lib's source-code and saw it call a different url from above:
https://geoip-js.com/geoip/v2.1/country/me?
trying this new url I saw it worked only WITHOUT authentication. I didn't understand why but anyway... it worked. Until I send the code to production at least.
With localhost it worked ok, but in production I get an error saying I have to register my domain.
The link provides in "register your domain" in this page: https://dev.maxmind.com/geoip/geolocate-an-ip/client-side-javascript?lang=en
leads to https://www.maxmind.com/en/accounts/790937/geoip/javascript/domains which asks me to enter the paid service registration page: https://www.maxmind.com/en/accounts/790937/geoip/javascript/domains
Is that it ? Client-side geolocation is only available as a paid service ?
So I want to know:
If there is a way to register domains for the free service, where do I register my domain?
If I can use https://geolite.info/geoip/v2.1/country/me?pretty url with id and license key in client-side, how to I get rid of the CORS message ?
I want to get the data without sending the user's IP, like when we access https://geolite.info/geoip/v2.1/country/me?pretty with id and license key.
Currently I want to use MaxMind's free data.

How to POST an issue stub on GitHub using the GitHub API using the logged in user, without authentification keys?

Users of my web application are expected to provide bug reports as a GitHub issue, with a pregenerated title and body.
This works perfectly fine using GET for small bodies:
const title = getLastErrorTitle();
const body = getAllTheLogMessages();
window.open(`https://github.com/theuser/therepo/issues/new?title=${encodeURIComponent(title)}&body=${encodeURIComponent(body)}`);
If the user is logged in, GitHub presents the user with a new issue with the title and body already filled out, perfect. If not, GitHub prompts the user to log in and it works the next time.
However, if the body is too large, the GET request fails because the URL becomes too long.
After consulting the manual I tried doing the same with POST but I get a 404 from GitHub with the following test request (jQuery for brevity):
$.ajax({
type: "POST",
url: "https://api.github.com/repos/theuser/therepo/issues",
data: data = {title: "Test", body: "Test Body"},
});
My suspicion is, that the GitHub API was not designed with my use case in mind, but that POST always requires authentication and creates the full issue in one go, without letting the user change it beforehand like it is possible with GET.
How can I transfer the functionality of the GET method over to the POST method? I just want GitHub to present the user, that is currently logged in inside the browser, with a prefilled issue, without needing a token.
You can't. Otherwise, it would be a major CSRF exploit.
However, you can use OAuth authentication that will allow your application to use some features : https://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps/
Or simply, redirect the user to a new issue page (for exemple with a simple HTML link <a>) with some automatic content, using this pattern :
https://github.com/{theUser}/{theRepo}/issues/new?body={theContentYouWhant}&title={theTitleYouWhant}
Example : https://github.com/CristalTeam/php-api-wrapper/issues/new?body=Hi,%20this%20is%20the%20body%20you%20want&title=Hello,%20this%20is%20a%20prefill%20issue
What I would suggest here is to generate a personal_auth_token at gihub and pass this token in the headers under Authorization field.
To generate personal_auth_token, login to github.com, go to settings -> developers settings -> Personal access tokens and generate one.
Pass this token in headers under Auhtorization: token. So in your AJAX request, it could look something like this:
$.ajax({
url: *yourUrl*
...
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', *token*));
},
});
One thing to note here is each of the developers POSTing to the repo will be requiring to generate their access token and you can't push this token on to a public Github repository because of obvious security breach. If you accidentally do so, the token is revoked immediately and you'll be required to create a new one.

Authenticate with Google as a specific User ID

I have set up Google Drive UI integration with my web app. When a user chooses to create a new file in Drive using my app, they are sent to
https://[mysite]?state={"folderId": "...", "action": "create", "userId":"..."}
I am signed in to multiple Google accounts (A and B) in my browser.
Account A opts to create a file, and is sent to my app with "userId": "[A's user id]" in the url.
However, with the gapi.auth2 JS library:
authInstance.signIn()
// Listen for sign in, and then:
authInstance.currentUser.get().getAuthResponse().access_token
Returns an access token for Account B.
This causes 404 errors when I try to create a file in folderId, which is only accessible to Account A.
How can my app authenticate with Google as the specific userId that opted to create a file?
The docs for Drive UI Integration do not seem to cover this issue, and the docs for Google Sign-In for Websites do not (as far as I can tell) provide a way to specify which account I want to sign in with (except through broad filters like "use a specific G Suite domain").
Update: The HTTP Google OAuth docs allow the client to specify a login_hint, which is an "email address or sub identifier" – it is not entirely clear what a "sub identifier" is. And, strangely, the Javascript API docs imply that login_hint is a response parameter, not something I can set.
Update 2 userId is an opaque Google-provoded integer value that I don't recognise. My app, Including the Drive upload, is fully client-side in JS and has no long-term data storage.

Can't submit anything to facebook page from facebook app

I now that this question was posted couple times but my problem is a little bit different. I try to submit for example event to my Page from Application.
I have private Profile on Facebook, Page and Application. Of course I'm admin of this page.
First thing I did was getting page access_token, so I went to https://developers.facebook.com/tools/explorer/ and in the URL I wrote /me/accounts/. Permission was set to manage_pages. I received access_token for my page.
Having access_token I connected my Application to the Page. So I made POST request to /[PAGE_ID]/tabs/ with app_id as a parameter and setting access_token of the Page. Now it's connected, I've checked it.
Now I try to submit some content by my Application. For example /[PAGE_ID]/events/ and passing parameters: name = Sample event, start_time = 2013-07-14T19:00:00-0700. And of course with the Application's access_token which I got by typing in the browser: https://graph.facebook.com/oauth/access_token?client_id=[APP_ID]&client_secret=[APP_SECRET]&grant_type=client_credentials. I got an error saying:
{
"error": {
"type": "Exception",
"message": "You must be an admin of the specified page to perform the requested action.",
"code": 1373019
}
}
I can post to this Page as a User but can't as an Application. My Application is of two types: Facebook Login and Facebook Tab. I've set permissions to publish_action and manage_pages publish_stream create_event.
What I did wrong?
Ok I solved the problem. Maybe it can be helpful for others. I don't know for what reason are those permissions https://developers.facebook.com/apps/[APP_ID]/permissions but the only thing I had to do was going to https://developers.facebook.com/tools/explorer/ and changing application from Graph API Explorer to my app and generating new access_token for privilages I needed. I don't know why they moved such crucial thing as permissions to the testing tool.

Instagram how to get access_token

I'm new to Instagram apps development and struggling with this issue for some time now. Basically, this is how it looks like:
I'm redirecting user to authorization url like this:
window.open("https://api.instagram.com/oauth/authorize/?client_id=" + igClientId + "&redirect_uri=" + igCallbackUrl + "&response_type=code", "_blank");
Then, when user will login, page reloads and Instagram CODE is added at the end of callback url ('?code=returned_by_instagram_code').
And this is the place where I've stuck.
How can I obtain returned code from url after page reloads (it is stored in cookies or session so I could access it in some way, or should I get it somehow through callback url and some function attached to it)?
How next, when I'll obtain the code, can I send (POST) request to Instagram for access_token?
Thank you in advance for any help.
PS. I'm using javascript without any frameworks (e.g. jquery) and this is the response that I'm looking for.
From the documentation on using Client-Side access token generation only (http://instagram.com/developer/authentication/) and the key thing you need to change is the responsecode in your URL to be: &response_type=token
Client-Side (Implicit) Authentication
If you’re building an app that does not have a server component (a purely javascript app, for instance), you’ll notice that it’s impossible to complete step three above to receive your access_token without also having to ship your client secret. You should never ship your client secret onto devices you don’t control. Then how do you get an access_token? Well the smart folks in charge of the OAuth 2.0 spec anticipated this problem and created the Implicit Authentication Flow.
Step One: Direct your user to our authorization URL
https://instagram.com/oauth/authorize/?client_id=CLIENT-ID&redirect_uri=REDIRECTURI&response_type=token
At this point, we present the user with a login screen and then a confirmation screen where they approve your app’s access to their Instagram data. Note that unlike the explicit flow the response type here is “token”.
Step Two: Receive the access_token via the URL fragment
Once the user has authenticated and then authorized your application, we’ll redirect them to your redirect_uri with the access_token in the url fragment. It’ll look like so:
http://your-redirect-uri#access_token=270740070.f59def8.d58713f2c81741c5b3686109306f98b4
Simply grab the access_token off the URL fragment and you’re good to go. If the user chooses not to authorize your application, you’ll receive the same error response as in the explicit flow
A simple example, get your token in registration app on api.instagran (https://instagram.com/developer/clients/register/). Make your login before:
var accessToken = '5e6e329062f047dd95ggj6c9df202c828';
$.ajax({
url: 'https://api.instagram.com/v1/media/popular',
dataType: 'jsonp',
type: 'GET',
data: {client_id: accessToken},
success: function(data){
console.log(data);
for(x in data.data){
$('ul').append('<li><img src="'+data.data[x].images.low_resolution.url+'"></li>');
}
},
error: function(data){
console.log(data);
}
});
The igCallbackUrl will redirect to a page. The code can be accessed as a GET parameter to that request.
Something like GET['code'] in php. If you give more details about the Server side framework then it will be helpful to answer your qwery.
You can use github.com/Instagram/instagram-javascript-sdk if you are using on Javascript.

Categories