I am new to backbone.js. I built a rest api with php and I want to connect to it with backbone.js. I am having a tough time with passing the http basic auth that my rest api uses for authentication.
I can access my rest api easily by using curl from the command line like this
curl -u username:password -X GET http://api.mysite.com/user
But when I try to do a fetch (which is pretty much all I am trying to do) I get a response from my rest api that the authentication failed.
Here is my call from backbone.js
user.fetch({headers:{'Authorization':'Basic username:password'}});
With backbone.js I am getting back the response I would expect when the basic auth fails. My question is, since I know my rest api with authenticate with curl, why won't it authenticate with the above javascript?
Also, when I look at the headers sent in the js console I don't see anything about Authorization.
UPDATE
I tried the plugin listed in the comment below but got the same result
Here is my code
var User=Backbone.Model.extend({
url: 'http://api.mysite.com/user'
});
var user=new User();
user.credentials = {
username: 'username',
password: 'password'
};
user.fetch();
The username and password need to be encoded with Baes64 before being sent.
One easy way to do this (at least for testing) is to configure all jQuery ajax requests to send the info (Backbone uses jQuery for the ajax calls):
$.ajaxSetup(
beforeSend: function(xhr){
xhr.setRequestHeader("Authorization", "Basic " + btoa("USERNAME" + ":" + "PASSWORD"));
}
);
Note that btoa is the function that will encode the params with Base64. Now you can call user.fetch() and it should work properly: you don't need to provide the credentials, because we've configured jQuery to send them for us (all the time).
Of course, depending on your situation (e.g. using multiple APIs), you might prefer to specify the beforeSend attribute within each request, or have it defined within a Backbone syncfunction.
I added "Authorization" to the allowed headers list and that did the trick.
header("Access-Control-Allow-Headers: Authorization, Origin, X-Requested-With, Content-Type, Accept");
Related
I am getting a preflight error 405: Method not allowed from the HERE API when I request autocomplete as per the documentation.
UPDATE 2:
I have since determined that Axios was adding my default.common authentication headers from my app's API client onto the HERE API client. Axios is supposed to keep those defaults separate per-client, but it seems that it doesn't ... at least not the version I have. I replaced the defaults with a per-client request interceptor and it worked fine. The request no longer triggers an OPTION pre-flight. No issue with HERE's API other than that it doesn't support OPTION method.
UPDATE:
The reason it fails is because HERE does not support the OPTIONS method, only the GET. So now the question is: Why does axios trigger an OPTIONS request when I don't set any headers? An XMLHttpRequest() based GET request does not trigger OPTIONS for the same URL. Something is happening with axios but I don't know what and I can't seem to investigate the headers that axios is sending.
ORIGINAL:
I've tried to find information about this error, as well as HTTP vs HTTPS. I haven't seen others having this problem so I feel like I must be making a simple error. The URL is generated correctly because it works when pasted directly into the browser for example.
const hereClient = axios.create({
baseURL: 'https://autocomplete.geocoder.api.here.com/6.2/'
})
async function searchHere (query) {
let searchTerms = query.split(' ').join('+')
let result = await hereClient.get('suggest.json', {
params: {
app_id: '<APPID>',
app_code: '<APPCODE>',
query: searchTerms
}
})
return processHereSearchResults(result.data)
}
The GET request fails on the OPTION preflight with a 405: Method not allowed. But if I paste the generated URL into a browser then it returns the expected results. For example:
https://autocomplete.geocoder.api.here.com/6.2/suggest.json?app_id=APPID&app_code=APPCODE&query=8131
returns:
{"suggestions":[{"label":"Česko, Brandýs nad Orlicí, 3123","language":"cs","countryCode":"CZE","locationId":"N . . .
Same result whether http or https.
I have since determined that Axios was adding my default.common authentication headers from my app's API client onto the HERE API client. Axios is supposed to keep those defaults separate per-client, but it seems that it doesn't ... at least not the version I have. I replaced the default header setting with a per-client request interceptor to set my authentication and it worked fine. The request no longer triggers an OPTION pre-flight. No issue with HERE's API other than that it doesn't support OPTION method.
I have the following code:
string tokenValue = "221e0a91-6530-4790-a969-d1da75b0afd2";
// Configure httpClient to use the above token.
httpClient.DefaultRequestHeaders.Add("token", tokenValue);
The subsequent calls (HEAD, POST, GET) all work fine.
When I try to do the same thing using Swagger Inspector, it fails. I am able to get a token using Swagger Inspector site, and I place the token into a HEAD call as follows:
But as I said, the call fails, with "Authorization has been denied for this request." message returned as an XML file.
I also tried the two other options available on the same page: Basic Authentication, and OAuth 2.0/JWT, all with HTTPS. They all fail.
How can I go about understanding why it's failing?
Also: Is what I am using above called "Bearer Authentication"?
I have below 2 things to mention from your screenshot:
Response for HEAD method never contains the response body, it always contains the response headers
for more details of HEAD: HEAD Request
But in your case response-body is also present (maybe of CML content type).
You should use OAuth 2.0/JWT option on the same page to pass the token along with your request.
To answer your question related to Bearer Authentication:
No, the one you are trying to use is not at all Bearer Authentication.
In your case, "token" will be considered as Custom/User HTTP Header.
Lets say we have SPA written in Angular 2 and have REST API using Spring Boot.
Both of them deployed in different servers. And now I have to protect this API via Facebook's OAuth2, but I don't know which grant type suits to my problem.
I don't want to be an auth server, I don't want facebook to be my resource server, instead my own REST API is supposed to be a resource server.
From FB I just want username or email or some identifier.
If I understood correctly I have to use implicit grant flow, because it's not a web application, correct me please, if I'm wrong.
Does "authorization code" grant also could be a choice ?
I really read almost all the threads related to oauth, spring security..
But I didn't find any info related to exactly SPA and REST API for separate servers.
Any link/resource related to above problem is appreciated.
Thanks in advance and sorry if I did something wrong, it's my very first post here.
You need to implement Implicit Grant flow https://oauth2.thephpleague.com/authorization-server/implicit-grant/
you need HTTPS for safety.
example:
OAuth Server: https://myoauthserver.com
restapi: https://myrestapi.com
client: https://myclient.com
send a get request to oauthserver "authorize" url with params
response_type = token (sometimes 'code')
redirect_uri = myclient.com or myclient.com/something (the one u assign while making an oauth client )
client id = dfuvhiurehvher (whatever id)
some providers require additional parameters like "scope".
when you send a request if everything works. you will be redirected to your client with the token in the url.
your request:
GET: https://myoauthserver.com/oauth/authorize?response_type=token&redirect_uri=https://myclient.com&client_id=yourClientIdHere
if successful you'll be redirected to
https://myclient.com?token=yourTokenValueIsHere
you can now use javascript to retrieve and store token value maybe to localStorage and attach it when sending requests to restapi (https://myrestapi.com)
heres an example request from auth0.com
$.ajax({
cache: false,
url: "http://localhost:7001/api/appointments",
headers: { "Authorization": "Bearer " + ATTACH_YOUR_TOKEN_VALUE_HERE }
});
for more details check this
https://auth0.com/docs/api-auth/tutorials/implicit-grant
I have been using FB api for some simple demo and everything was quite easy with the authentication. Now I have to do something similar with twitter v1.1 but there is something that I really don't understand...
Example:
I want to do this request:
https://api.twitter.com/1.1/search/tweets.json?q=q=%23freebandnames
the problem is that I have to be authenticated, anyone have some examples? I don't want to create a twitter connection because I don't need different users to be connected to my applicaiton. I have just to perform some simple search request but I can't understand how to use the authentication parameters. Which type of Ajax request I have to use in order to perform the REST request authenticated??? (Obviously I have my secret token and my access secret token) but how to use them????
THanks in advance for answers
You can use this javascript library: codebird-js with the "Application-only auth".
or
Do it yourself: everything is explained in the documentation.
Basically you need to follow 3 steps (and you should do the 2 first just once):
An application encodes its consumer key and secret into a specially encoded set of credentials.
An application makes a request to the POST oauth2/token endpoint to exchange these credentials for a bearer token.
When accessing the REST API, the application uses the bearer token to authenticate.
The steps are detailed in the documentation.
You can do the first 2 separately and when you get your bearer token, you need to add a specific HTTP Header (Authorization) in each request with your bearer token (that's the 3rd step). With jQuery it could be something like that:
$.ajax({
headers: { Authorization: 'Bearer '+$my_bearer_token },
url: 'https://api.twitter.com/1.1/search/tweets.json?q='+$search
}).done(function (data) {
// Play with the data
});
I am trying to access a REST web service using HTTP GET request.
For a example following URI provides Rest web service that return all the available parts for the given category.
http://localhost:8080/mycompany/parts/category
I want to authenticate/authorize users who are accessing above REST request in each time and I want to pass User authentication details (User Name and Token) with the HTTP Get Request.
Is there a possibility to cater to the above requirement in REST HTTP GET request (using HTTP header or query parameters)?
or
Is it better to use HTTP POST instead of HTTP GET?
Since you are getting information, you should use "Get". Here's the code that I use (it is Restlet based) for adding the oauth_token to the request...
import org.restlet.data.Reference;
import org.restlet.ext.oauth.OAuthUser;
import org.restlet.representation.Representation;
import org.restlet.resource.ClientResource;
Reference commitsRef = new Reference(Consts.RESOURCE_BASE + "commitments/");
OAuthUser u = (OAuthUser) request.getClientInfo().getUser();
String token = u.getAccessToken();
ref.addQueryParameter("oauth_token", token);
ClientResource commitsResource = new ClientResource(getContext(), commitsRef);
Representation commitsRep = commitsResource.get();
As mentioned, this is Restlet based, but there is probably something similar in the framework you are using. (And if you are not using a framework, Restlet can make this easier).
if you are using restlet than good because restlet have rich api for rest framework
but without this if you want to authenticate than
you can do same thing with GET or POST
but send your credential data trough cookie
and read same cookie using #CookieParam from server side
in this way you can easily authenticate user.