These examples use the OpenStreetMap implementation of OAuth 1.0a. See a full implementation of the examples in the Mapping North Korea GitHub repository.
Using OAuth on the client side exposes the keys and secrets of both the consumer and the user, which is a security risk. This page explains the OAuth process on the server side using Node.js. The examples below use the request
package. Error handling is not included in these examples.
Before we start: OAuth 1.0 vs OAuth 1.0a
A quick overview of the difference between OAuth 1.0 and OAuth 1.0a. The main difference is that the Callback URL is supplied in a different place and it uses a token verifier. In the image below you can see the differences marked with \"1.0\" and \"1.0a\".
Source: https://support.smartbear.com/readyapi/docs/requests/auth/types/oauth1/about.html
1. Making the user log in
To be able to send OAuth authenticated requests we need an access token and to get that access token the user needs to log in. So when the user clicks on the login button (or something like it) on your front end, you need to generate a link that will send the user to the relevant OAuth provider site that has the login window.
The req
object is from the request that the user sends from the client to the Node.js server. We use this to save the response data in the user's session.
request.post({
// The url to get the request token from.
url: "https://www.openstreetmap.org/oauth/request_token",
oauth: {
// Supply a callback url. OSM uses the callback url later to return/send the key data to your application/website.
callback: "https://YOURWEBSITE.COM/api/oauth/callback",
// Consumer key and secret are given to the developer after registering the application on the official OSM site.
consumer_key: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
consumer_secret: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
}, (err, rs, body) => {
// You can use the querystring package (const qs = require("querystring");) to parse the data to a javascript object.
var bodyObject = qs.parse(body);
// Put the token and token secret in the session of this user.
req.session.oauth_token = bodyObject.oauth_token;
req.session.oauth_token_secret = bodyObject.oauth_token_secret;
res.send("https://www.openstreetmap.org/oauth/authorize?oauth_token=" + bodyObject.oauth_token);
});
The res.send
sends the url to the front end. This URL is used by the user to authorize. You could also just send back the token and build the url on the front end of course. Open a popup window or new tab with this URL so that the user can authorize on the official OSM site.
2. Confirm/verify and get the access token
After the user uses the previously mentioned popup window or new tab to authorize itself on the official OSM website, the OSM server will send a request to the previously supplied callback URL. Make a route for this callback URL and then finish the OAuth process by making a final OAuth request to get the access token and secret. These will be used to make requests to the OSM API later on.
request.post({
url: "https://www.openstreetmap.org/oauth/access_token",
oauth: {
// Supply the consumer key, consumer secret, access token and access secret for every request to the API.
consumer_key: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
consumer_secret: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
token: req.query.oauth_token,
token_secret: req.session.oauth_token_secret,
// The OSM callback contains this verifier. You need it to finalize the OAuth authentication process.
verifier: req.query.oauth_verifier
}
}, (err, rs, body) => {
var bodyObject = qs.parse(body);
// Save the access token and access secret in the user's session.
req.session.access_token = bodyObject.oauth_token;
req.session.access_token_secret = bodyObject.oauth_token_secret;
res.sendFile(global.appRoot + "/public/land.html");
});
What you do after saving the access token in the session depends on how you build your front-end. I return a landing page that closes itself and calls a function on the client side. In another app I simply redirect res.redirect(baseUrl);
to the base url of the client.
You could also already send a request, because returning to the front end is not necessary of course.
3. (Optional) Example of sending a request
You\'re ready to start sending requests to the OSM API. Here is an example of receiving user details of the authorized user.
request({
url: "https://www.openstreetmap.org/api/0.6/user/details",
method: "GET",
oauth: {
// Supply the consumer key, consumer secret, access token and access secret for every request to the API.
consumer_key: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
consumer_secret: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
token: req.session.access_token,
token_secret: req.session.access_token_secret
},
headers: {
// The OSM API doesn't use JSON, so don't forget to set the content type as XML.
"content-type": "text/xml"
}
}, (err, rs, body) => {
// Do anything with the body. (XML)
});
Thanks given to you,