Clientside GitHub Authentication - javascript

I'm using a Javascript to do Basic Authentication with GitHub. For example, the following shell command gets a token from Github:
curl -i -u uaername:password -k -d "{\"scopes\": [\"repo\"]}" https://api.github.com/authorizations
How do you achieve that with jQuery and AJAX?

Including Basic Auth Data in HTTP Headers with jQuery
You can include basic auth details in the header using the Authorization field. You already understand how jQuery works. This snippet has the bits you're missing:
let auth = btoa(username + ":" + password);
jQuery.ajax({
url: ...,
headers: { Authorization: "Basic " + auth }
...
});
Note: btoa and atob (pronounced B to A and A to B) are builtin functions, and convert to and from Base64. See the MDN docs for more information.

Are you asking whether there is a way to get an oAuth token purely from the client side? If so, the answer is no.
But, you have some work arounds.
Github.js: https://github.com/michael/github
Gatekeeper is an open source server side component which can help with oAuth tokens management:
https://github.com/prose/gatekeeper
You could also use something like Firebase with simple login and in this case you don't need to manage any server side services:
https://www.firebase.com/docs/security/simple-login-github.html

Related

What is wrong here? Getting amazon users email in alexa

I'm trying to develop an alexa skill and I would like to get the user's email and then compare it to those of a database. I found many examples on the web but they are all written in SDK v1 which is no longer supported.
following instructions and after reading the documentation I wrote this piece of code only that it doesn't work either on AWS or in the spoken test on alexa developer. What am I doing wrong?
var accessToken = this.event.context.System.apiAccessToken;
Bearer < ACCESS_TOKEN >
Host: api.amazonalexa.it
Accept: application/json
Authorization: Bearer MQEWY...6fnLok
GET https://api.amazonalexa.com/v2/accounts/~current/settings/Profile.email;
This repo has example code on using customer profile: GitHub: alexa-cookbook
Search for the line:
const email = await client.getProfileEmail();

Creating a Shopify Order via postman / Shopify API

I ran into this tutorial using every technology in the world which is supposed to show how to build a react app from the ground up to leverage the shopify API. However there also this page describing a simple API call to do more or less what I need.
The goal is to have an entirely custom (extremely simple) checkout process that ends up in the shopify system. It would go something like this:
Stripe purchase ok -> shopify order saved -> thank you page redirect.
EDIT: It appears that the format https://api_key:api_secret.#my-store.myshopify.com/admin/api/2019-07/orders.json solves the authentication problem. The call:
GET https://key:secret#my-test-store.myshopify.com/admin/api/2019-07/orders.json
returns a pleasant
{
"orders": []
} so the authentication is a-ok.
However, doing a POST https://key:secret#my-test-store.myshopify.com/admin/api/2019-07/orders.json
Seems to return a cryptic page, instead of an error like so (which simply leads to your demo store/app):
So, in summary, I have a store, an authorized app (which successfully authenticates) so how do I add an order for an existing SKU programmatically?
Are you sure there are no cookies on the request? Because I can reproduce your exact issue if I add cookies.
It might be easier to use curl in order to have absolute clarity into what is being posted. For example:
# Edit to change app hostname, key/secret, and product/variant/customer ids
curl -X POST 'https://key:secret#so57018447.myshopify.com/admin/api/2019-07/orders.json' \
-H 'Content-Type: application/json' \
-d '{
"order": {
"line_items": [
{
"product_id": 2017449607219,
"variant_id": 17985741619251,
"quantity": 1
}
],
"customer": {
"id": 1257159000115
},
"financial_status": "pending"
}
}
'
Response:
{
"order": {
"id":952834392115,
"email":"",
"closed_at":null,
"created_at":"2019-07-15T14:38:18-04:00",
...
But if you want to stick with Postman, here are the supporting screenshots showing success without cookies, and failure with:
Confirming there are no cookies set:
Successful post to orders.json endpoint:
Now, add a cookie:
And I get the response shown in your question:
If you read the documentation of the private apps
Shopify doesn't support cookies in POST requests that use basic HTTP authentication. Any POST requests that use basic authentication and include cookies will fail with a 200 error code. Using cookies with basic authentication can expose your app to CSRF attacks, such as session hijacking.
https://help.shopify.com/en/api/getting-started/authentication/private-authentication
This is on purpose, doing this on a client side is criminal. If you are doing something server side then it is ok to use basic auth. But on client side you shouldn't be using it
If you want to use in postman then you need to use it with access_token
Private apps can authenticate with Shopify by including the request header X-Shopify-Access-Token: {access_token}, where {access_token} is replaced by your private app's Admin API password.

Let's chat authentication via ajax request

I've deployed a Let's Chat application for my own server.
However, instead of using currently built, original Let's Chat web application I would like to develop my own, using its API.
And according to Let's Chat wiki:
Revoke an API Token
In the top-left dropdown menu:
Select "Auth tokens"
Click "Revoke token"
Choose "Yes". This will delete any previously generated token.
Basic Authentication
Use the API token as the username when authenticating. The password
can be set to anything, but it must not be blank (simply because most
clients require it).
So far I've generated own token and tried to send GET request to retrieve all rooms that I have in the app, but I've got an error: 401 - Unauthorized - I've tried to send this request with { data: my_token, password: my_random_password } credentials but without success. So my main question is: how exactly I can authenticate with Let's Chat API using ajax request?
I couldn't find any API url / endpoint dedicated for such task - please help.
EDIT:
I've tried also setting headers but it still doesn't work:
$.ajax({
url: CHAT_URL + 'rooms',
beforeSend: function(xhr){
xhr.setRequestHeader('username', 'NTczYzZ1111111111111111111JiMWE3MGUwYThiNzZhYjhmYjFjOWJkOTQ5ZDQ2YjhjNWUyMzkwNmMzYjhjMQ==');
xhr.setRequestHeader('password', '123qwe');
}
}).done(function(resp){
console.log('1');
console.log(resp);
}).done(function(resp){
console.log('2');
console.log(resp);
});
From that wiki page:
Use the API token as the Bearer token.
This is done by setting the header Authentication to the value bearer YOUR_TOKEN_HERE
So,
xhr.setRequestHeader('Authentication', 'bearer NTczYzZ1111111111111111111JiMWE3MGUwYThiNzZhYjhmYjFjOWJkOTQ5ZDQ2YjhjNWUyMzkwNmMzYjhjMQ==');
If you want to use basic authentication, this answers that question
How to use Basic Auth with jQuery and AJAX?

Curl to Javascript

I am making a Chrome Extension that talks to a website via an api. I want it to pass information about a current tab to my website via a cors request.
I have a POST api request already working. It looks like this:
...
var url = "https://webiste.com/api/v1/users/sendInfo"
...
xhr.send(JSON.stringify({user_name:user_name, password:password, info:info}));
Its corresponding curl statement is something like this:
curl -X POST https://website.com/api/v1/users/sendInfo -d '{ username:"username", password:"password", info: "Lot's of info" }' --header "Content-type: application/json
But, this is not as secure as we want. I was told to mirror the curl command below:
curl --basic -u username:password <request url> -d '{ "info": "Lot's of info" }'
But, one cannot just write curl into javascript.
If someone could either supply javascript that acts like this curl statement or explain exactly what is going on in that basic option of the curl script I think that I could progress from there.
The curl command is setting a basic Authorization header. This can be done in JavaScript like
var url = "https://webiste.com/api/v1/users/sendInfo",
username = "...",
password = "...";
xhr.open('POST', url, true, username, password);
xhr.send(...);
This encodes the username/password using base 64, and sets the Authorization header.
Edit As arcyqwerty mentioned, this is no more secure than sending username/password in the request body JSON. The advantage of using the basic authentication approach is that it's a standard way of specifying user credentials which integrates well with many back-ends. If you need security, make sure to send your data over HTTPS.
curl is the curl binary which fetches URLs.
--basic tells curl to use "HTTP Basic Authentication"
-u username:password tells curl supply a given username/password for the authentication. This authentication information is base64 encoded in the request. Note the emphasis on encoded which is different from encrypted. HTTP basic auth is not secure (although it can be made more secure by using an HTTPS channel)
-d tells curl to send the following as the data for the request
You may be able to specify HTTP basic authentication in your request by making the request to https://username:password#website.com/api/v1/users/sendInfo

How would I form a correct POST request to LinkedIn to exchange the temp auth code for the access token and is SSL3 the cause?

I'm still a bit confused about how to form the correct POST request to LinkedIn to exchange the already received temporary authorization code for the user's access token as described in the LinkedIn docs at https://developer.linkedin.com/documents/authentication in step 3b.
There it says a POST request should be made, but instead of the POST request format, the docs give this URL with query parameters:
https://www.linkedin.com/uas/oauth2/accessToken?grant_type=authorization_code
&code=AUTHORIZATION_CODE
&redirect_uri=YOUR_REDIRECT_URI
&client_id=YOUR_API_KEY
&client_secret=YOUR_SECRET_KEY
I'm using server-side JavaScript and would like to form the proper POST request. Does this look correct?
r = 'POST /uas/oauth2/accessToken HTTP/1.1' + crlf;
r += 'Host: www.linkedin.com' + crlf + crlf;
r += parameters;
Where crlf is '\r\n' and parameters would be in the body and would be:
grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=YOUR_REDIRECT_URI&client_id=YOUR_API_KEY&client_secret=YOUR_SECRET_KEY
with the upper-case values being replaced by the actual values for our app and the user.
Then the request itself would be sent to https://www.linkedin.com/uas/oauth2/accessToken using a function I have for making HTTP requests.
Does that seem correct? Is that sufficient for forming a proper POST request?
Must I also include Referer, Content-Type and Content-Length headers? If so, should my request actually look like this?
r = 'POST /uas/oauth2/accessToken HTTP/1.1' + crlf;
r += 'Host: www.linkedin.com' + crlf ;
r += 'Referer: http://' + site.txMainServer + '/LinkedProfile' + crlf;
r += 'Content-Type: application/x-www-form-urlencoded' + crlf;
r += 'Content-Length: ' + parameters.length + crlf + crlf;
r += parameters;
Where site.txMainServer is the server's URL.
New info: If I try the above code, rather than returning JSON with the access token, the following error is returned when I make my POST request: "* Connection error: 1590".
New info 2: Somebody told me that LinkedIn would also accept a GET request. So instead of a POST I tried a GET request in the exact form of the URL shown above in the LinkedIn documentation. But I also get a "* Connection error: 1590" if I try that. So I am stuck.
New info 3: Since it is an HTTPS request I tried replacing the Host header above with
Host: www.linkedin.com:443
but that didn't help. I still get the same "* Connection error: 1590".
New info 4: I believe the 1590 error is a "failure to make an SSL connection" error from my server. I have since tested by making successful SSL POST requests from my server to other SSL sites with the exact same headers and parameters (adjusting the Host of course to match the other server) for testing and have returned successful replies. So there is something about the LinkedIn server that is different. It wants some different format of a POST request, but I don't know what it is.
New Info 5: It appears our server is trying to make a POST request via SSL3 to exchange the temporary authentication code for the access token needed to make API calls, but we are experiencing handshake failures. Is SSL3 not supported at all for the LinkedIn API now?
It's just not clear to me why, if LinkedIn docs say they want a POST they instead give an example showing a full URL with query parameters, rather than the exact format of the POST request they want.
It appears I am not doing it the way LinkedIn wants, and would appreciate any assistance here. If I could just see an example of the correct format of the POST request I'm sure I can proceed from there! But it's not in the LinkedIn docs.
Thanks,
doug
I'm not familiar with server-side js (you mean nodejs?).
so shot in the dark: some companies require params both in the URL & POST body and linkedin require HTTPS request, maybe www.linkedin.com is not right.
PS. can't edit comments,just post here;(
I believe I found the answer. At https://developer.linkedin.com/forum/oauth2-api-not-working-all-sudden LinkedIn employees post the following in response to people having problems which seem much like mine:
"In light of the recent disclosure of the "Poodle" SSL vulnerability, LinkedIn
is joining the large number of services that have actively removed support for
SSLv3, effective immediately. If you are experiencing errors related to
HTTPS-based communication with our APIs, please ensure you are using a
client/library that supports TLS 1.0+ instead of SSLv3 to avoid disruption.""
and
"There is no fix for this issue. It is the result of an unfixable vulnerability
in the SSLv3 protocol itself, which is well outside of LinkedIn's control. We
will not be re-enabling support for this. You will have to use a library that
can make a different SSL connection."
It appears we have to upgrade our SSL or cannot proceed.
doug

Categories